-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Sort/Import Tokens in Extension (#27184)
## **Description** ### This PR adds Token sorting to the Asset List page, and also moves Token importing to the top of the Token List. A few of the main changes introduced: 1. Include `NativeToken` in `TokenList` component to be included in sorting logic, and treated (as far as sorting is concerned) as any other token in the list 2. Intoduce a `tokenSortConfig` into state that keeps track of the sort order, the key being sorted by, and the direction of the sort order. Also includes an action to update this state. 3. Introduce a `useEffect` that subscribes to `tokenSortConfig` as well as a few other application state variables to update and sort tokenList when appropriate. 2. Clean up `asset-list` component, and move some of it's relevant code into the `useAccountTotalFiatBalance` **Acceptance Criteria:** 1. Tokens should be sorted by default by declining balance 2. Sort controls should sort tokens alphabetically, and by decreasing fiat token balance 3. Sort order should persist through refresh 4. Sort order should persist after app is closed and reopened 5. When a token gets imported, it should be included in the sort list, in the correct order in the list **A couple of disclaimers. There are still (at least) two bugs that I discovered that were not caught by tests:** 1. ~~When toggling preferred currency setting, Native Token sorted incorrectly by decreasing fiat balance~~ ✅ fixed 2. ~~When switching between accounts, token list does not update~~ ✅ fixed [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27184?quickstart=1) ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MMASSETS-356 ## **Manual testing steps** 1. Go to AssetList page, and click dropdown and select option to sort by 2. Tokens should sort, and remain sorted through refresh and application close/open (it is in state) 4. Importing tokens should import them into the sort order ## **Screenshots/Recordings** https://github.com/user-attachments/assets/8ecca5e4-093f-4651-946e-31c612795427 ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.
- Loading branch information
Showing
55 changed files
with
1,486 additions
and
239 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { migrate, version } from './130'; | ||
|
||
const oldVersion = 129; | ||
|
||
describe(`migration #${version}`, () => { | ||
it('updates the version metadata', async () => { | ||
const oldStorage = { | ||
meta: { version: oldVersion }, | ||
data: {}, | ||
}; | ||
const newStorage = await migrate(oldStorage); | ||
expect(newStorage.meta).toStrictEqual({ version }); | ||
}); | ||
describe(`migration #${version}`, () => { | ||
it('updates the preferences with a default tokenSortConfig', async () => { | ||
const oldStorage = { | ||
meta: { version: oldVersion }, | ||
data: { | ||
PreferencesController: { | ||
preferences: {}, | ||
}, | ||
}, | ||
}; | ||
const expectedData = { | ||
PreferencesController: { | ||
preferences: { | ||
tokenSortConfig: { | ||
key: 'tokenFiatAmount', | ||
order: 'dsc', | ||
sortCallback: 'stringNumeric', | ||
}, | ||
}, | ||
}, | ||
}; | ||
const newStorage = await migrate(oldStorage); | ||
|
||
expect(newStorage.data).toStrictEqual(expectedData); | ||
}); | ||
|
||
it('does nothing if the preferences already has a tokenSortConfig', async () => { | ||
const oldStorage = { | ||
meta: { version: oldVersion }, | ||
data: { | ||
PreferencesController: { | ||
preferences: { | ||
tokenSortConfig: { | ||
key: 'fooKey', | ||
order: 'foo', | ||
sortCallback: 'fooCallback', | ||
}, | ||
}, | ||
}, | ||
}, | ||
}; | ||
|
||
const newStorage = await migrate(oldStorage); | ||
|
||
expect(newStorage.data).toStrictEqual(oldStorage.data); | ||
}); | ||
|
||
it('does nothing to other preferences if they exist without a tokenSortConfig', async () => { | ||
const oldStorage = { | ||
meta: { version: oldVersion }, | ||
data: { | ||
PreferencesController: { | ||
preferences: { | ||
existingPreference: true, | ||
}, | ||
}, | ||
}, | ||
}; | ||
|
||
const expectedData = { | ||
PreferencesController: { | ||
preferences: { | ||
existingPreference: true, | ||
tokenSortConfig: { | ||
key: 'tokenFiatAmount', | ||
order: 'dsc', | ||
sortCallback: 'stringNumeric', | ||
}, | ||
}, | ||
}, | ||
}; | ||
|
||
const newStorage = await migrate(oldStorage); | ||
|
||
expect(newStorage.data).toStrictEqual(expectedData); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { hasProperty, isObject } from '@metamask/utils'; | ||
import { cloneDeep } from 'lodash'; | ||
|
||
type VersionedData = { | ||
meta: { version: number }; | ||
data: Record<string, unknown>; | ||
}; | ||
export const version = 130; | ||
/** | ||
* This migration adds a tokenSortConfig to the user's preferences | ||
* | ||
* | ||
* @param originalVersionedData - Versioned MetaMask extension state, exactly what we persist to dist. | ||
* @param originalVersionedData.meta - State metadata. | ||
* @param originalVersionedData.meta.version - The current state version. | ||
* @param originalVersionedData.data - The persisted MetaMask state, keyed by controller. | ||
* @returns Updated versioned MetaMask extension state. | ||
*/ | ||
export async function migrate( | ||
originalVersionedData: VersionedData, | ||
): Promise<VersionedData> { | ||
const versionedData = cloneDeep(originalVersionedData); | ||
versionedData.meta.version = version; | ||
transformState(versionedData.data); | ||
return versionedData; | ||
} | ||
function transformState( | ||
state: Record<string, unknown>, | ||
): Record<string, unknown> { | ||
if ( | ||
hasProperty(state, 'PreferencesController') && | ||
isObject(state.PreferencesController) && | ||
hasProperty(state.PreferencesController, 'preferences') && | ||
isObject(state.PreferencesController.preferences) && | ||
!state.PreferencesController.preferences.tokenSortConfig | ||
) { | ||
state.PreferencesController.preferences.tokenSortConfig = { | ||
key: 'tokenFiatAmount', | ||
order: 'dsc', | ||
sortCallback: 'stringNumeric', | ||
}; | ||
} | ||
return state; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.