Skip to content

Commit

Permalink
Merge branch 'main' into fix/revert-nft-grid
Browse files Browse the repository at this point in the history
  • Loading branch information
sahar-fehri authored Feb 3, 2025
2 parents 815f79d + d01cf65 commit e0231ad
Show file tree
Hide file tree
Showing 18 changed files with 172 additions and 72 deletions.
10 changes: 4 additions & 6 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,10 @@ app/components/UI/Swaps @MetaMask/swaps-engineers
# Notifications Team
app/components/Views/Notifications @MetaMask/notifications
app/components/Views/Settings/NotificationsSettings @MetaMask/notifications
app/components/UI/Notifications @MetaMask/notifications
app/reducers/notification @MetaMask/notifications
app/actions/notification @MetaMask/notifications
app/selectors/notification @MetaMask/notifications
app/util/notifications @MetaMask/notifications
app/store/util/notifications @MetaMask/notifications
**/Notifications/** @MetaMask/notifications
**/Notification/** @MetaMask/notifications
**/notifications/** @MetaMask/notifications
**/notification/** @MetaMask/notifications

# Identity Team
app/actions/identity @MetaMask/identity
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/create-release-pr-v2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:

create-release-pr:
needs: generate-build-version
uses: MetaMask/github-tools/.github/workflows/create-release-pr.yml@v0.1.0
uses: MetaMask/github-tools/.github/workflows/create-release-pr.yml@f8467f14f7d09c5b980565f15ebc8003b0272138
with:
platform: mobile
base-branch: ${{ inputs.base-branch }}
Expand Down
12 changes: 1 addition & 11 deletions app/components/Nav/App/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,6 @@ import SDKSessionModal from '../../Views/SDK/SDKSessionModal/SDKSessionModal';
import ExperienceEnhancerModal from '../../../../app/components/Views/ExperienceEnhancerModal';
import { MetaMetrics } from '../../../core/Analytics';
import trackErrorAsAnalytics from '../../../util/metrics/TrackError/trackErrorAsAnalytics';
import generateDeviceAnalyticsMetaData from '../../../util/metrics/DeviceAnalyticsMetaData/generateDeviceAnalyticsMetaData';
import generateUserSettingsAnalyticsMetaData from '../../../util/metrics/UserSettingsAnalyticsMetaData/generateUserProfileAnalyticsMetaData';
import LedgerSelectAccount from '../../Views/LedgerSelectAccount';
import OnboardingSuccess from '../../Views/OnboardingSuccess';
import DefaultSettings from '../../Views/OnboardingSuccess/DefaultSettings';
Expand Down Expand Up @@ -745,15 +743,7 @@ const App = (props) => {

useEffect(() => {
const initMetrics = async () => {
const metrics = MetaMetrics.getInstance();
await metrics.configure();
// identify user with the latest traits
// run only after the MetaMetrics is configured
const consolidatedTraits = {
...generateDeviceAnalyticsMetaData(),
...generateUserSettingsAnalyticsMetaData(),
};
await metrics.addTraitsToUser(consolidatedTraits);
await MetaMetrics.getInstance().configure();
};

initMetrics().catch((err) => {
Expand Down
4 changes: 0 additions & 4 deletions app/components/Nav/App/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ describe('App', () => {
);
await waitFor(() => {
expect(mockMetrics.configure).toHaveBeenCalledTimes(1);
expect(mockMetrics.addTraitsToUser).toHaveBeenNthCalledWith(1, {
deviceProp: 'Device value',
userProp: 'User value',
});
});
});
});
11 changes: 6 additions & 5 deletions app/components/UI/Swaps/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ import {
selectCurrentCurrency,
} from '../../../selectors/currencyRateController';
import { selectContractExchangeRates } from '../../../selectors/tokenRatesController';
import { selectAccounts } from '../../../selectors/accountTrackerController';
import { selectAccountsByChainId } from '../../../selectors/accountTrackerController';
import { selectContractBalances } from '../../../selectors/tokenBalancesController';
import { selectSelectedInternalAccountFormattedAddress } from '../../../selectors/accountsController';
import AccountSelector from '../Ramp/components/AccountSelector';
Expand Down Expand Up @@ -182,7 +182,7 @@ const MAX_TOP_ASSETS = 20;
function SwapsAmountView({
swapsTokens,
swapsControllerTokens,
accounts,
accountsByChainId,
selectedAddress,
chainId,
selectedNetworkClientId,
Expand All @@ -196,6 +196,7 @@ function SwapsAmountView({
currentCurrency,
setLiveness,
}) {
const accounts = accountsByChainId[chainId];
const navigation = useNavigation();
const route = useRoute();
const { colors } = useTheme();
Expand Down Expand Up @@ -963,9 +964,9 @@ SwapsAmountView.propTypes = {
tokensWithBalance: PropTypes.arrayOf(PropTypes.object),
tokensTopAssets: PropTypes.arrayOf(PropTypes.object),
/**
* Map of accounts to information objects including balances
* Map of chainId to accounts to information objects including balances
*/
accounts: PropTypes.object,
accountsByChainId: PropTypes.object,
/**
* A string that represents the selected address
*/
Expand Down Expand Up @@ -1011,7 +1012,7 @@ SwapsAmountView.propTypes = {
const mapStateToProps = (state) => ({
swapsTokens: swapsTokensSelector(state),
swapsControllerTokens: swapsControllerTokens(state),
accounts: selectAccounts(state),
accountsByChainId: selectAccountsByChainId(state),
balances: selectContractBalances(state),
selectedAddress: selectSelectedInternalAccountFormattedAddress(state),
conversionRate: selectConversionRate(state),
Expand Down
4 changes: 2 additions & 2 deletions app/components/Views/BrowserTab/BrowserTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1307,10 +1307,10 @@ export const BrowserTab: React.FC<BrowserTabProps> = ({
<ErrorBoundary navigation={navigation} view="BrowserTab">
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={styles.wrapper}
style={[styles.wrapper, !isTabActive && styles.hide]}
>
<View
style={[styles.wrapper, !isTabActive && styles.hide]}
style={styles.wrapper}
{...(Device.isAndroid() ? { collapsable: false } : {})}
>
<BrowserUrlBar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ const mockInitialState = {
balance: '0x0',
},
},
accountsByChainId: {
'0x1': {
'0xd018538C87232FF95acbCe4870629b75640a78E7': {
balance: '0x0',
},
},
},
},
AccountsController: {
internalAccounts: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';

import { useNavigation } from '@react-navigation/native';

import {
newAssetTransaction,
setSelectedAsset,
} from '../../../../../actions/transaction';
import Routes from '../../../../../constants/navigation/Routes';
import { selectAccounts } from '../../../../../selectors/accountTrackerController';
import { selectAccountsByChainId } from '../../../../../selectors/accountTrackerController';
import { selectSelectedInternalAccount } from '../../../../../selectors/accountsController';
import { doENSReverseLookup } from '../../../../../util/ENSUtils';
import { renderFromWei, hexToBN } from '../../../../../util/number';
Expand All @@ -27,11 +25,11 @@ const SendFlowAddressFrom = ({
}: SFAddressFromProps) => {
const navigation = useNavigation();

const accounts = useSelector(selectAccounts);

const ticker = useSelector((state: RootState) =>
selectNativeCurrencyByChainId(state, chainId as Hex),
);
const accountsByChainId = useSelector(selectAccountsByChainId);
const accounts = accountsByChainId[chainId];

const selectedInternalAccount = useSelector(selectSelectedInternalAccount);
const checksummedSelectedAddress = selectedInternalAccount
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ exports[`Amount should convert ERC-20 token value to USD 1`] = `
style={
{
"alignSelf": "flex-end",
"color": "#0376c9",
"color": "#6a737d",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down Expand Up @@ -1148,7 +1148,7 @@ exports[`Amount should convert ETH to USD 1`] = `
style={
{
"alignSelf": "flex-end",
"color": "#0376c9",
"color": "#6a737d",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down Expand Up @@ -1864,7 +1864,7 @@ exports[`Amount should convert USD to ERC-20 token value 1`] = `
style={
{
"alignSelf": "flex-end",
"color": "#0376c9",
"color": "#6a737d",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down Expand Up @@ -2597,7 +2597,7 @@ exports[`Amount should convert USD to ETH 1`] = `
style={
{
"alignSelf": "flex-end",
"color": "#0376c9",
"color": "#6a737d",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down Expand Up @@ -3330,7 +3330,7 @@ exports[`Amount should display correct balance 1`] = `
style={
{
"alignSelf": "flex-end",
"color": "#0376c9",
"color": "#6a737d",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down Expand Up @@ -4045,7 +4045,7 @@ exports[`Amount should not show a warning when conversion rate is available 1`]
style={
{
"alignSelf": "flex-end",
"color": "#0376c9",
"color": "#6a737d",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down Expand Up @@ -5434,15 +5434,15 @@ exports[`Amount should proceed if balance is sufficient while on Native primary
}
>
<TouchableOpacity
disabled={false}
disabled={true}
onPress={[Function]}
style={{}}
>
<Text
style={
{
"alignSelf": "flex-end",
"color": "#0376c9",
"color": "#6a737d",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down Expand Up @@ -6228,7 +6228,7 @@ exports[`Amount should render correctly 1`] = `
style={
{
"alignSelf": "flex-end",
"color": "#0376c9",
"color": "#6a737d",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down Expand Up @@ -6938,7 +6938,7 @@ exports[`Amount should show a warning when conversion rate is not available 1`]
style={
{
"alignSelf": "flex-end",
"color": "#0376c9",
"color": "#6a737d",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down Expand Up @@ -7565,15 +7565,15 @@ exports[`Amount should show an error message if balance is insufficient 1`] = `
}
>
<TouchableOpacity
disabled={false}
disabled={true}
onPress={[Function]}
style={{}}
>
<Text
style={
{
"alignSelf": "flex-end",
"color": "#0376c9",
"color": "#6a737d",
"fontFamily": "EuclidCircularB-Regular",
"fontSize": 12,
"fontWeight": "400",
Expand Down
22 changes: 20 additions & 2 deletions app/components/Views/confirmations/SendFlow/Amount/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { PureComponent } from 'react';
import BigNumber from 'bignumber.js';
import { fontStyles } from '../../../../../styles/common';
import {
StyleSheet,
Expand Down Expand Up @@ -164,6 +165,13 @@ const createStyles = (colors) =>
alignSelf: 'flex-end',
textTransform: 'uppercase',
},
maxTextDisabled: {
...fontStyles.normal,
fontSize: 12,
color: colors.text.alternative,
alignSelf: 'flex-end',
textTransform: 'uppercase',
},
actionMax: {
flexDirection: 'row',
alignItems: 'center',
Expand Down Expand Up @@ -1457,6 +1465,10 @@ class Amount extends PureComponent {
const colors = this.context.colors || mockTheme.colors;
const styles = createStyles(colors);

const isEstimateedTotalGasValid = estimatedTotalGas
? BigNumber(estimatedTotalGas).gt(0)
: false;

return (
<SafeAreaView
edges={['bottom']}
Expand Down Expand Up @@ -1516,10 +1528,16 @@ class Amount extends PureComponent {
{!selectedAsset.tokenId && (
<TouchableOpacity
style={styles.actionMaxTouchable}
disabled={!estimatedTotalGas}
disabled={!isEstimateedTotalGasValid}
onPress={this.useMax}
>
<Text style={styles.maxText}>
<Text
style={
isEstimateedTotalGasValid
? styles.maxText
: styles.maxTextDisabled
}
>
{strings('transaction.use_max')}
</Text>
</TouchableOpacity>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ import {
isTestNet,
isMainnetByChainId,
isMultiLayerFeeNetwork,
fetchEstimatedMultiLayerL1Fee,
TESTNET_FAUCETS,
isTestNetworkWithFaucet,
getDecimalChainId,
} from '../../../../../util/networks';
import { fetchEstimatedMultiLayerL1Fee } from '../../../../../util/networks/engineNetworkUtils';
import Text from '../../../../Base/Text';
import { removeFavoriteCollectible } from '../../../../../actions/collectibles';
import { SafeAreaView } from 'react-native-safe-area-context';
Expand Down
45 changes: 44 additions & 1 deletion app/core/AppStateEventListener.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jest.mock('./processAttribution', () => ({
jest.mock('./Analytics/MetaMetrics');

const mockMetrics = {
trackEvent: jest.fn().mockImplementation(() => Promise.resolve()),
trackEvent: jest.fn(),
enable: jest.fn(() => Promise.resolve()),
addTraitsToUser: jest.fn(() => Promise.resolve()),
isEnabled: jest.fn(() => true),
Expand Down Expand Up @@ -105,6 +105,49 @@ describe('AppStateEventListener', () => {
);
});

it('identifies user when app becomes active', () => {
jest
.spyOn(ReduxService, 'store', 'get')
.mockReturnValue({} as unknown as ReduxStore);

mockAppStateListener('active');
jest.advanceTimersByTime(2000);

expect(mockMetrics.addTraitsToUser).toHaveBeenCalledTimes(1);
expect(mockMetrics.addTraitsToUser).toHaveBeenCalledWith({
'Batch account balance requests': 'OFF',
'Enable OpenSea API': 'OFF',
'NFT Autodetection': 'OFF',
'Theme': undefined,
'applicationVersion': expect.any(Promise),
'currentBuildNumber': expect.any(Promise),
'deviceBrand': 'Apple',
'operatingSystemVersion': 'ios',
'platform': 'ios',
'security_providers': '',
'token_detection_enable': 'OFF',
});
});

it('logs error when identifying user fails', () => {
jest
.spyOn(ReduxService, 'store', 'get')
.mockReturnValue({} as unknown as ReduxStore);
const testError = new Error('Test error');
mockMetrics.addTraitsToUser.mockImplementation(() => {
throw testError;
});

mockAppStateListener('active');
jest.advanceTimersByTime(2000);

expect(Logger.error).toHaveBeenCalledWith(
testError,
'AppStateManager: Error processing app state change'
);
expect(mockMetrics.trackEvent).not.toHaveBeenCalled();
});

it('handles errors gracefully', () => {
jest
.spyOn(ReduxService, 'store', 'get')
Expand Down
Loading

0 comments on commit e0231ad

Please sign in to comment.