From 8714c9c0294f73c02c2a04def63439c649573bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Tue, 25 Sep 2018 11:03:23 +0200 Subject: [PATCH] Sort manager apps by marketcap --- package.json | 2 +- src/components/ManagerPage/AppsList.js | 62 +++++++++++++++++--------- src/components/ManagerPage/index.js | 7 ++- src/helpers/countervalues.js | 29 ++++++++++++ yarn.lock | 6 +-- 5 files changed, 79 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index 942552b7..6c84f1ac 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "@ledgerhq/hw-transport": "^4.13.0", "@ledgerhq/hw-transport-node-hid": "4.22.0", "@ledgerhq/ledger-core": "2.0.0-rc.7", - "@ledgerhq/live-common": "^3.5.1", + "@ledgerhq/live-common": "^3.7.1", "animated": "^0.2.2", "async": "^2.6.1", "axios": "^0.18.0", diff --git a/src/components/ManagerPage/AppsList.js b/src/components/ManagerPage/AppsList.js index f589ea7f..bf1fd550 100644 --- a/src/components/ManagerPage/AppsList.js +++ b/src/components/ManagerPage/AppsList.js @@ -7,15 +7,13 @@ import { translate } from 'react-i18next' import { connect } from 'react-redux' import { compose } from 'redux' import type { Device, T } from 'types/common' -import type { Application, ApplicationVersion, DeviceInfo } from 'helpers/types' +import type { ApplicationVersion, DeviceInfo } from 'helpers/types' +import { getFullListSortedCryptoCurrencies } from 'helpers/countervalues' import { developerModeSelector } from 'reducers/settings' - import listApps from 'commands/listApps' import listAppVersions from 'commands/listAppVersions' - import installApp from 'commands/installApp' import uninstallApp from 'commands/uninstallApp' - import Box from 'components/base/Box' import Space from 'components/base/Space' import Modal, { ModalBody, ModalFooter, ModalTitle, ModalContent } from 'components/base/Modal' @@ -26,13 +24,11 @@ import Spinner from 'components/base/Spinner' import Button from 'components/base/Button' import TranslatedError from 'components/TranslatedError' import TrackPage from 'analytics/TrackPage' - import IconInfoCircle from 'icons/InfoCircle' import ExclamationCircleThin from 'icons/ExclamationCircleThin' import Update from 'icons/Update' import Trash from 'icons/Trash' import CheckCircle from 'icons/CheckCircle' - import { FreezeDeviceChangeEvents } from './HookDeviceChange' import ManagerApp, { Container as FakeManagerAppContainer } from './ManagerApp' import AppSearchBar from './AppSearchBar' @@ -102,29 +98,53 @@ class AppsList extends PureComponent { _unmounted = false - filterAppVersions = (applicationsList, compatibleAppVersionsList) => { - if (!this.props.isDevMode) { - return compatibleAppVersionsList.filter(version => { - const app = applicationsList.find(e => e.id === version.app) - if (app) { - return app.category !== 2 - } + prepareAppList = ({ applicationsList, compatibleAppVersionsList, sortedCryptoCurrencies }) => { + const filtered = this.props.isDevMode + ? compatibleAppVersionsList.slice(0) + : compatibleAppVersionsList.filter(version => { + const app = applicationsList.find(e => e.id === version.app) + if (app) { + return app.category !== 2 + } - return false - }) - } - return compatibleAppVersionsList + return false + }) + + const sortedCryptoApps = [] + + // sort by crypto first + sortedCryptoCurrencies.forEach(crypto => { + const app = filtered.find( + item => item.name.toLowerCase() === crypto.managerAppName.toLowerCase(), + ) + if (app) { + filtered.splice(filtered.indexOf(app), 1) + sortedCryptoApps.push(app) + } + }) + + return sortedCryptoApps.concat(filtered) } async fetchAppList() { try { const { deviceInfo } = this.props - const applicationsList: Array = await listApps.send().toPromise() - const compatibleAppVersionsList = await listAppVersions.send(deviceInfo).toPromise() - const filteredAppVersionsList = this.filterAppVersions( + + const [ applicationsList, compatibleAppVersionsList, - ) + sortedCryptoCurrencies, + ] = await Promise.all([ + listApps.send().toPromise(), + listAppVersions.send(deviceInfo).toPromise(), + getFullListSortedCryptoCurrencies(), + ]) + + const filteredAppVersionsList = this.prepareAppList({ + applicationsList, + compatibleAppVersionsList, + sortedCryptoCurrencies, + }) if (!this._unmounted) { this.setState({ diff --git a/src/components/ManagerPage/index.js b/src/components/ManagerPage/index.js index 7c9631b2..24ee0407 100644 --- a/src/components/ManagerPage/index.js +++ b/src/components/ManagerPage/index.js @@ -4,12 +4,11 @@ import React, { PureComponent, Fragment } from 'react' import invariant from 'invariant' import { openURL } from 'helpers/linking' import { urls } from 'config/urls' - import type { Device } from 'types/common' import type { DeviceInfo } from 'helpers/types' +import { getFullListSortedCryptoCurrencies } from 'helpers/countervalues' import Dashboard from './Dashboard' - import ManagerGenuineCheck from './ManagerGenuineCheck' import HookDeviceChange from './HookDeviceChange' @@ -30,6 +29,10 @@ const INITIAL_STATE = { class ManagerPage extends PureComponent { state = INITIAL_STATE + componentDidMount() { + getFullListSortedCryptoCurrencies() // start fetching the crypto currencies ordering + } + // prettier-ignore handleSuccessGenuine = ({ device, deviceInfo }: { device: Device, deviceInfo: DeviceInfo }) => { // eslint-disable-line react/no-unused-prop-types this.setState({ isGenuine: true, device, deviceInfo }) diff --git a/src/helpers/countervalues.js b/src/helpers/countervalues.js index 7f8801b1..1f45137c 100644 --- a/src/helpers/countervalues.js +++ b/src/helpers/countervalues.js @@ -12,6 +12,8 @@ import { intermediaryCurrency, } from 'reducers/settings' import logger from 'logger' +import { listCryptoCurrencies } from '@ledgerhq/live-common/lib/helpers/currencies' +import type { CryptoCurrency } from '@ledgerhq/live-common/lib/types' const pairsSelector = createSelector( currenciesSelector, @@ -52,6 +54,7 @@ const addExtraPollingHooks = (schedulePoll, cancelPoll) => { } } +// TODO we should be able to pass-in our network() function const CounterValues = createCounterValues({ log: (...args) => logger.log('CounterValues:', ...args), getAPIBaseURL: () => LEDGER_COUNTERVALUES_API, @@ -61,4 +64,30 @@ const CounterValues = createCounterValues({ addExtraPollingHooks, }) +let sortCache +export const getFullListSortedCryptoCurrencies: () => Promise = () => { + if (!sortCache) { + sortCache = CounterValues.fetchTickersByMarketcap().then( + tickers => { + const list = listCryptoCurrencies().slice(0) + const prependList = [] + tickers.forEach(ticker => { + const item = list.find(c => c.ticker === ticker) + if (item) { + list.splice(list.indexOf(item), 1) + prependList.push(item) + } + }) + return prependList.concat(list) + }, + () => { + sortCache = null // reset the cache for the next time it comes here to "try again" + return listCryptoCurrencies() // fallback on default sort + }, + ) + } + + return sortCache +} + export default CounterValues diff --git a/yarn.lock b/yarn.lock index 71c73832..9e0fb6ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1549,9 +1549,9 @@ npm "^5.7.1" prebuild-install "^2.2.2" -"@ledgerhq/live-common@^3.5.1": - version "3.5.1" - resolved "https://registry.yarnpkg.com/@ledgerhq/live-common/-/live-common-3.5.1.tgz#dab3eb061f361999a9e04ef564808831faac61ea" +"@ledgerhq/live-common@^3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@ledgerhq/live-common/-/live-common-3.7.1.tgz#5ce1895920d2eae6c454c2c72612dc9afd11adec" dependencies: axios "^0.18.0" bignumber.js "^7.2.1"