Skip to content

Commit

Permalink
chore: integrate with APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
guanbinrui committed Aug 25, 2020
1 parent 870f477 commit 2684349
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 29 deletions.
88 changes: 68 additions & 20 deletions src/plugins/Trader/UI/TrendingView.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,55 @@
import React, { useState, useEffect } from 'react'
import { makeStyles, Avatar, Typography, Card, CardHeader, IconButton, CardActions } from '@material-ui/core'
import {
makeStyles,
Avatar,
Typography,
Card,
CardHeader,
IconButton,
CardActions,
Theme,
createStyles,
} from '@material-ui/core'
import { useAsync } from 'react-use'
import SettingsIcon from '@material-ui/icons/Settings'
import classNames from 'classnames'
import ArrowDropUpIcon from '@material-ui/icons/ArrowDropUp'
import ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown'
import { SettingsDialog } from './SettingsDialog'
import { Platform, Currency, resolvePlatformName, Settings } from '../type'
import { getCurrenies } from '../apis'
import { PortalShadowRoot, portalShadowRoot } from '../../../utils/jss/ShadowRootPortal'
import { setStorage, getStorage } from '../../../utils/browser.storage'
import { getActivatedUI } from '../../../social-network/ui'
import stringify from 'json-stable-stringify'
import { currentTrendingViewSettings, currentTrendingViewPlatformSettings } from '../settings'
import { useValueRef } from '../../../utils/hooks/useValueRef'
import Services from '../../../extension/service'
import { formatCurrency } from '../../Wallet/formatter'
import { useColorStyles } from '../../../utils/theme'

const network = getActivatedUI().networkIdentifier

const useStyles = makeStyles({
root: {},
header: {
display: 'flex',
},
body: {},
avatar: {},
amount: {},
})
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {},
header: {
display: 'flex',
},
body: {},
avatar: {},
percentage: {
marginLeft: theme.spacing(1),
},
}),
)

export interface TrendingViewProps extends withClasses<KeysInferFromUseStyles<typeof useStyles>> {
keyword: string
}

export function TrendingView(props: TrendingViewProps) {
const classes = useStyles()
const color = useColorStyles()
const [settingsDialogOpen, setSettingsDialogOpen] = useState(false)

const [platform, setPlatform] = useState(Platform.COIN_GECKO)
Expand All @@ -40,9 +60,10 @@ export function TrendingView(props: TrendingViewProps) {
const trendingPlatformSettings = useValueRef<string>(currentTrendingViewPlatformSettings[network])

//#region currency & platform
const { value: currencies = [], loading: loadingCurrencies, error } = useAsync(() => getCurrenies(platform), [
platform,
])
const { value: currencies = [], loading: loadingCurrencies } = useAsync(
() => Services.Plugin.invokePlugin('maskbook.trader', 'getCurrenies', platform),
[platform],
)

// sync platform
useEffect(() => {
Expand All @@ -65,25 +86,52 @@ export function TrendingView(props: TrendingViewProps) {
}, [trendingSettings, currencies.length])
//#endregion

//#region coins info
const { value: coinInfo, loading: loadingCoinInfo, error } = useAsync(async () => {
if (!currency) return null
return Services.Plugin.invokePlugin(
'maskbook.trader',
'getCoinTrendingByKeyword',
props.keyword,
platform,
currency,
)
}, [platform, currency, props.keyword])
//#endregion
if (loadingCurrencies || !currency) return null
if (loadingCoinInfo || !coinInfo) return null

return (
<>
<Card className={classes.root} elevation={0} component="article">
<CardHeader
className={classes.header}
avatar={
<Avatar src="https://cdn4.iconfinder.com/data/icons/logos-and-brands/512/45_Bitcoin_logo_logos-512.png" />
}
avatar={<Avatar src={coinInfo.coin.image_url} alt={coinInfo.coin.symbol} />}
action={
<IconButton size="small" onClick={() => setSettingsDialogOpen(true)}>
<SettingsIcon />
</IconButton>
}
title={<Typography variant="h6">{`BTC / ${currency.name}`}</Typography>}
title={
<Typography variant="h6">{`${coinInfo.coin.symbol.toUpperCase()} / ${
currency.name
}`}</Typography>
}
subheader={
<Typography variant="body1">
<span>{`${currency.name} 12,223`}</span>
<span>(1.2%)</span>
<span>{`${currency.symbol ?? currency.name} ${formatCurrency(
coinInfo.market.current_price,
)}`}</span>
{coinInfo.market.price_change_24h ? (
<span
className={classNames(
classes.percentage,
coinInfo.market.price_change_24h > 0 ? color.success : color.error,
)}>
{coinInfo.market.price_change_24h > 0 ? '\u25B2 ' : '\u25BC '}
{coinInfo.market.price_change_24h.toFixed(2)}%
</span>
) : null}
</Typography>
}
/>
Expand Down
5 changes: 2 additions & 3 deletions src/plugins/Trader/apis/coingecko/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import type { Currency } from '../../type'

const BASE_URL = 'https://api.coingecko.com/api/v3'

//#region get currency
Expand Down Expand Up @@ -54,11 +52,12 @@ export interface CoinInfo {
localization: Record<string, string>
market_cap_rank: number
market_data: {
current_price: Record<string, number>
high_24h: Record<string, number>
low_24h: Record<string, number>
market_cap: Record<string, number>
market_cap_rank: number
price_change_24h: number
price_change_percentage_24h: number
total_supply: number
total_volume: Record<string, number>
}
Expand Down
10 changes: 6 additions & 4 deletions src/plugins/Trader/apis/coinmarketcap/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import CURRENCY_DATA from './currency.json'
// proxy: https://web-api.coinmarketcap.com/v1
const BASE_URL = 'https://coinmarketcap.provide.maskbook.com/v1'

// porxy: https://widgets.coinmarketcap.com/v2
const WIDGET_BASE_URL = 'https://coinmarketcap.provide.maskbook.com/v2'
const WIDGET_BASE_URL = 'https://widgets.coinmarketcap.com/v2'

export interface Status {
credit_count: number
Expand Down Expand Up @@ -73,8 +72,11 @@ export interface CoinInfo {
last_updated: number
}

export async function getCoinInfo(id: number, currency: string) {
export async function getCoinInfo(id: string, currency: string) {
const response = await fetch(`${WIDGET_BASE_URL}/ticker/${id}/?ref=widget&convert=${currency}`)
return response.json() as Promise<CoinInfo>
return response.json() as Promise<{
data: CoinInfo
status: Status
}>
}
//#endregion
55 changes: 54 additions & 1 deletion src/plugins/Trader/apis/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Platform, Currency } from '../type'
import { Platform, Currency, Coin, Trending } from '../type'
import * as coinGeckoAPI from './coingecko'
import * as coinMarketCapAPI from './coinmarketcap'

Expand All @@ -17,3 +17,56 @@ export async function getCurrenies(platform: Platform): Promise<Currency[]> {
description: x.name,
}))
}

export async function getCoins(platform: Platform): Promise<Coin[]> {
if (platform === Platform.COIN_GECKO) return coinGeckoAPI.getAllCoins()
return (await coinMarketCapAPI.getAllCoins()).data.map((x) => ({
id: String(x.id),
name: x.name,
symbol: x.symbol,
}))
}

export async function getCoinInfo(id: string, platform: Platform, currency: Currency): Promise<Trending> {
if (platform === Platform.COIN_GECKO) {
const info = await coinGeckoAPI.getCoinInfo(id)
return {
coin: {
id,
name: info.name,
symbol: info.symbol,
image_url: info.image.thumb,
},
currency,
platform,
market: {
current_price: info.market_data.current_price[currency.id],
total_volume: info.market_data.total_volume[currency.id],
price_change_24h: info.market_data.price_change_percentage_24h,
},
}
}
const info = await coinMarketCapAPI.getCoinInfo(id, currency.name.toUpperCase())
return {
coin: {
id,
name: info.data.name,
symbol: info.data.symbol,
image_url: `https://s2.coinmarketcap.com/static/img/coins/64x64/${id}.png`,
},
currency,
platform,
market: {
current_price: info.data.quotes[currency.name.toUpperCase()].price,
total_volume: info.data.quotes[currency.name.toUpperCase()].volume_24h,
price_change_24h: info.data.quotes[currency.name.toUpperCase()].percent_change_24h,
},
}
}

export async function getCoinTrendingByKeyword(keyword: string, platform: Platform, currency: Currency) {
const coins = await getCoins(platform)
const coin = coins.find((x) => x.symbol.toLowerCase() === keyword.toLowerCase())
if (!coin) return null
return getCoinInfo(coin.id, platform, currency)
}
2 changes: 1 addition & 1 deletion src/plugins/Trader/services.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export function noop() {}
export * from './apis'
20 changes: 20 additions & 0 deletions src/plugins/Trader/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,26 @@ export interface Currency {
description?: string
}

export interface Coin {
id: string
name: string
symbol: string
image_url?: string
}

export interface Market {
current_price: number
total_volume?: number
price_change_24h?: number
}

export interface Trending {
platform: Platform
coin: Coin
currency: Currency
market: Market
}

export function resolveCurrencyName(currency: Currency) {
return [
currency.name,
Expand Down
4 changes: 4 additions & 0 deletions src/plugins/Wallet/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ export function formatBalance(balance: BigNumber, decimals: number, precision: n

return raw.indexOf('.') > -1 ? raw.replace(/0+$/, '').replace(/\.$/, '') : raw
}

export function formatCurrency(balance: number) {
return balance.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,')
}

0 comments on commit 2684349

Please sign in to comment.