Compare commits

..

1 Commits

Author SHA1 Message Date
Daniel Ternyak 8c95213240
Merge pull request #1075 from MyCryptoHQ/develop
Tag Beta 0.2.1
2018-02-12 19:02:18 -06:00
485 changed files with 21025 additions and 23649 deletions

2
.gitignore vendored
View File

@ -56,5 +56,3 @@ webpack_config/server.csr
v8-compile-cache-0/
package-lock.json
yarn.lock

View File

@ -1 +0,0 @@
common/translations

View File

@ -1,7 +1,6 @@
# MyCrypto Beta (VISIT [MyCryptoHQ/mycrypto.com](https://github.com/MyCryptoHQ/mycrypto.com) for the current site)<br/>Just looking to download? Grab our [latest release](https://github.com/MyCryptoHQ/MyCrypto/releases)
[![Greenkeeper badge](https://badges.greenkeeper.io/MyCryptoHq/MyCrypto.svg)](https://greenkeeper.io/)
[![Coverage Status](https://coveralls.io/repos/github/MyCryptoHQ/MyCrypto/badge.svg?branch=develop)](https://coveralls.io/github/MyCryptoHQ/MyCrypto?branch=develop)
## Running the App

View File

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { Provider, connect } from 'react-redux';
import { Provider } from 'react-redux';
import { withRouter, Switch, Redirect, HashRouter, Route, BrowserRouter } from 'react-router-dom';
// Components
import Contracts from 'containers/Tabs/Contracts';
@ -9,47 +9,32 @@ import SendTransaction from 'containers/Tabs/SendTransaction';
import Swap from 'containers/Tabs/Swap';
import SignAndVerifyMessage from 'containers/Tabs/SignAndVerifyMessage';
import BroadcastTx from 'containers/Tabs/BroadcastTx';
import CheckTransaction from 'containers/Tabs/CheckTransaction';
import ErrorScreen from 'components/ErrorScreen';
import PageNotFound from 'components/PageNotFound';
import LogOutPrompt from 'components/LogOutPrompt';
import { TitleBar } from 'components/ui';
import { Store } from 'redux';
import { pollOfflineStatus, TPollOfflineStatus } from 'actions/config';
import { pollOfflineStatus } from 'actions/config';
import { AppState } from 'reducers';
import { RouteNotFound } from 'components/RouteNotFound';
import { RedirectWithQuery } from 'components/RedirectWithQuery';
import 'what-input';
import { setUnitMeta, TSetUnitMeta } from 'actions/transaction';
import { getNetworkUnit } from 'selectors/config';
interface OwnProps {
interface Props {
store: Store<AppState>;
}
interface StateProps {
networkUnit: string;
}
interface DispatchProps {
pollOfflineStatus: TPollOfflineStatus;
setUnitMeta: TSetUnitMeta;
}
type Props = OwnProps & StateProps & DispatchProps;
interface State {
error: Error | null;
}
class RootClass extends Component<Props, State> {
export default class Root extends Component<Props, State> {
public state = {
error: null
};
public componentDidMount() {
this.props.pollOfflineStatus();
this.props.setUnitMeta(this.props.networkUnit);
this.props.store.dispatch(pollOfflineStatus());
}
public componentDidCatch(error: Error) {
@ -82,7 +67,6 @@ class RootClass extends Component<Props, State> {
<Route path="/contracts" component={Contracts} />
<Route path="/ens" component={ENS} exact={true} />
<Route path="/sign-and-verify-message" component={SignAndVerifyMessage} />
<Route path="/tx-status" component={CheckTransaction} exact={true} />
<Route path="/pushTx" component={BroadcastTx} />
<RouteNotFound />
</Switch>
@ -136,7 +120,8 @@ const LegacyRoutes = withRouter(props => {
history.push('/account/info');
break;
case '#check-tx-status':
return <RedirectWithQuery from={pathname} to={'/tx-status'} />;
history.push('/check-tx-status');
break;
}
}
@ -148,14 +133,3 @@ const LegacyRoutes = withRouter(props => {
</Switch>
);
});
const mapStateToProps = (state: AppState) => {
return {
networkUnit: getNetworkUnit(state)
};
};
export default connect(mapStateToProps, {
pollOfflineStatus,
setUnitMeta
})(RootClass);

View File

@ -48,14 +48,6 @@ export function changeNodeIntent(payload: string): interfaces.ChangeNodeIntentAc
};
}
export type TChangeNodeForce = typeof changeNodeForce;
export function changeNodeForce(payload: string): interfaces.ChangeNodeForceAction {
return {
type: TypeKeys.CONFIG_NODE_CHANGE_FORCE,
payload
};
}
export type TAddCustomNode = typeof addCustomNode;
export function addCustomNode(
payload: interfaces.AddCustomNodeAction['payload']

View File

@ -36,11 +36,6 @@ export interface ChangeNodeIntentAction {
type: TypeKeys.CONFIG_NODE_CHANGE_INTENT;
payload: string;
}
/*** Force Change Node ***/
export interface ChangeNodeForceAction {
type: TypeKeys.CONFIG_NODE_CHANGE_FORCE;
payload: string;
}
/*** Add Custom Node ***/
export interface AddCustomNodeAction {

View File

@ -10,7 +10,6 @@ export enum TypeKeys {
CONFIG_NODE_WEB3_UNSET = 'CONFIG_NODE_WEB3_UNSET',
CONFIG_NODE_CHANGE = 'CONFIG_NODE_CHANGE',
CONFIG_NODE_CHANGE_INTENT = 'CONFIG_NODE_CHANGE_INTENT',
CONFIG_NODE_CHANGE_FORCE = 'CONFIG_NODE_CHANGE_FORCE',
CONFIG_ADD_CUSTOM_NODE = 'CONFIG_ADD_CUSTOM_NODE',
CONFIG_REMOVE_CUSTOM_NODE = 'CONFIG_REMOVE_CUSTOM_NODE',

View File

@ -1,19 +0,0 @@
import * as interfaces from './actionTypes';
import { TypeKeys } from './constants';
export type TFetchGasEstimates = typeof fetchGasEstimates;
export function fetchGasEstimates(): interfaces.FetchGasEstimatesAction {
return {
type: TypeKeys.GAS_FETCH_ESTIMATES
};
}
export type TSetGasEstimates = typeof setGasEstimates;
export function setGasEstimates(
payload: interfaces.SetGasEstimatesAction['payload']
): interfaces.SetGasEstimatesAction {
return {
type: TypeKeys.GAS_SET_ESTIMATES,
payload
};
}

View File

@ -1,14 +0,0 @@
import { TypeKeys } from './constants';
import { GasEstimates } from 'api/gas';
export interface FetchGasEstimatesAction {
type: TypeKeys.GAS_FETCH_ESTIMATES;
}
export interface SetGasEstimatesAction {
type: TypeKeys.GAS_SET_ESTIMATES;
payload: GasEstimates;
}
/*** Union Type ***/
export type GasAction = FetchGasEstimatesAction | SetGasEstimatesAction;

View File

@ -1,4 +0,0 @@
export enum TypeKeys {
GAS_FETCH_ESTIMATES = 'GAS_FETCH_ESTIMATES',
GAS_SET_ESTIMATES = 'GAS_SET_ESTIMATES'
}

View File

@ -1,3 +0,0 @@
export * from './actionCreators';
export * from './actionTypes';
export * from './constants';

View File

@ -27,10 +27,10 @@ export function loadBityRatesSucceededSwap(
};
}
export type TLoadShapeshiftRatesSucceededSwap = typeof loadShapeshiftRatesSucceededSwap;
export type TLoadShapeshiftSucceededSwap = typeof loadShapeshiftRatesSucceededSwap;
export function loadShapeshiftRatesSucceededSwap(
payload: interfaces.LoadShapeshiftRatesSucceededSwapAction['payload']
): interfaces.LoadShapeshiftRatesSucceededSwapAction {
payload
): interfaces.LoadShapshiftRatesSucceededSwapAction {
return {
type: TypeKeys.SWAP_LOAD_SHAPESHIFT_RATES_SUCCEEDED,
payload
@ -59,27 +59,13 @@ export function loadBityRatesRequestedSwap(): interfaces.LoadBityRatesRequestedS
};
}
export type TLoadShapeshiftRatesRequestedSwap = typeof loadShapeshiftRatesRequestedSwap;
export function loadShapeshiftRatesRequestedSwap(): interfaces.LoadShapeshiftRatesRequestedSwapAction {
export type TLoadShapeshiftRequestedSwap = typeof loadShapeshiftRatesRequestedSwap;
export function loadShapeshiftRatesRequestedSwap(): interfaces.LoadShapeshiftRequestedSwapAction {
return {
type: TypeKeys.SWAP_LOAD_SHAPESHIFT_RATES_REQUESTED
};
}
export type TLoadBityRatesFailedSwap = typeof loadBityRatesFailedSwap;
export function loadBityRatesFailedSwap(): interfaces.LoadBityRatesFailedSwapAction {
return {
type: TypeKeys.SWAP_LOAD_BITY_RATES_FAILED
};
}
export type TLoadShapeshiftFailedSwap = typeof loadShapeshiftRatesFailedSwap;
export function loadShapeshiftRatesFailedSwap(): interfaces.LoadShapeshiftRatesFailedSwapAction {
return {
type: TypeKeys.SWAP_LOAD_SHAPESHIFT_RATES_FAILED
};
}
export type TStopLoadBityRatesSwap = typeof stopLoadBityRatesSwap;
export function stopLoadBityRatesSwap(): interfaces.StopLoadBityRatesSwapAction {
return {

View File

@ -8,7 +8,7 @@ export interface Pairs {
}
export interface SwapInput {
label: string;
id: string;
amount: number | string;
}
@ -43,7 +43,7 @@ export interface LoadBityRatesSucceededSwapAction {
payload: ApiResponse;
}
export interface LoadShapeshiftRatesSucceededSwapAction {
export interface LoadShapshiftRatesSucceededSwapAction {
type: TypeKeys.SWAP_LOAD_SHAPESHIFT_RATES_SUCCEEDED;
payload: ApiResponse;
}
@ -59,18 +59,12 @@ export interface RestartSwapAction {
export interface LoadBityRatesRequestedSwapAction {
type: TypeKeys.SWAP_LOAD_BITY_RATES_REQUESTED;
payload?: null;
}
export interface LoadShapeshiftRatesRequestedSwapAction {
export interface LoadShapeshiftRequestedSwapAction {
type: TypeKeys.SWAP_LOAD_SHAPESHIFT_RATES_REQUESTED;
}
export interface LoadBityRatesFailedSwapAction {
type: TypeKeys.SWAP_LOAD_BITY_RATES_FAILED;
}
export interface LoadShapeshiftRatesFailedSwapAction {
type: TypeKeys.SWAP_LOAD_SHAPESHIFT_RATES_FAILED;
payload?: null;
}
export interface ChangeStepSwapAction {
@ -246,14 +240,12 @@ export interface ShowLiteSendAction {
export type SwapAction =
| ChangeStepSwapAction
| InitSwap
| LoadBityRatesSucceededSwapAction
| LoadShapshiftRatesSucceededSwapAction
| DestinationAddressSwapAction
| RestartSwapAction
| LoadBityRatesRequestedSwapAction
| LoadBityRatesSucceededSwapAction
| LoadBityRatesFailedSwapAction
| LoadShapeshiftRatesRequestedSwapAction
| LoadShapeshiftRatesSucceededSwapAction
| LoadShapeshiftRatesFailedSwapAction
| LoadShapeshiftRequestedSwapAction
| StopLoadBityRatesSwapAction
| StopLoadShapeshiftRatesSwapAction
| BityOrderCreateRequestedSwapAction

View File

@ -7,8 +7,6 @@ export enum TypeKeys {
SWAP_RESTART = 'SWAP_RESTART',
SWAP_LOAD_BITY_RATES_REQUESTED = 'SWAP_LOAD_BITY_RATES_REQUESTED',
SWAP_LOAD_SHAPESHIFT_RATES_REQUESTED = 'SWAP_LOAD_SHAPESHIFT_RATES_REQUESTED',
SWAP_LOAD_BITY_RATES_FAILED = 'SWAP_LOAD_BITY_RATES_FAILED',
SWAP_LOAD_SHAPESHIFT_RATES_FAILED = 'SWAP_LOAD_SHAPESHIFT_RATES_FAILED',
SWAP_STOP_LOAD_BITY_RATES = 'SWAP_STOP_LOAD_BITY_RATES',
SWAP_STOP_LOAD_SHAPESHIFT_RATES = 'SWAP_STOP_LOAD_SHAPESHIFT_RATES',
SWAP_ORDER_TIME = 'SWAP_ORDER_TIME',

View File

@ -81,10 +81,7 @@ const setGasPriceField = (payload: SetGasPriceFieldAction['payload']): SetGasPri
});
type TReset = typeof reset;
const reset = (payload: ResetAction['payload'] = { include: {}, exclude: {} }): ResetAction => ({
type: TypeKeys.RESET,
payload
});
const reset = (): ResetAction => ({ type: TypeKeys.RESET });
export {
TInputGasLimit,

View File

@ -5,22 +5,23 @@ import {
SetTokenToMetaAction
} from 'actions/transaction';
export type TSetTokenTo = typeof setTokenTo;
export const setTokenTo = (payload: SetTokenToMetaAction['payload']): SetTokenToMetaAction => ({
type TSetTokenBalance = typeof setTokenValue;
type TSetUnitMeta = typeof setUnitMeta;
type TSetTokenTo = typeof setTokenTo;
const setTokenTo = (payload: SetTokenToMetaAction['payload']): SetTokenToMetaAction => ({
type: TypeKeys.TOKEN_TO_META_SET,
payload
});
export type TSetTokenValue = typeof setTokenValue;
export const setTokenValue = (
payload: SetTokenValueMetaAction['payload']
): SetTokenValueMetaAction => ({
const setTokenValue = (payload: SetTokenValueMetaAction['payload']): SetTokenValueMetaAction => ({
type: TypeKeys.TOKEN_VALUE_META_SET,
payload
});
export type TSetUnitMeta = typeof setUnitMeta;
export const setUnitMeta = (payload: SetUnitMetaAction['payload']): SetUnitMetaAction => ({
const setUnitMeta = (payload: SetUnitMetaAction['payload']): SetUnitMetaAction => ({
type: TypeKeys.UNIT_META_SET,
payload
});
export { TSetUnitMeta, TSetTokenBalance, TSetTokenTo, setUnitMeta, setTokenValue, setTokenTo };

View File

@ -7,9 +7,6 @@ import { SignAction } from './sign';
import { SwapAction } from './swap';
import { CurrentAction } from './current';
import { SendEverythingAction } from './sendEverything';
import { State as FieldState } from 'reducers/transaction/fields';
import { State as MetaState } from 'reducers/transaction/meta';
import { State as SignState } from 'reducers/transaction/sign';
export * from './broadcast';
export * from './fields';
@ -22,18 +19,6 @@ export * from './sendEverything';
export interface ResetAction {
type: TypeKeys.RESET;
payload: {
include: {
fields?: (keyof FieldState)[];
meta?: (keyof MetaState)[];
sign?: (keyof SignState)[];
};
exclude: {
fields?: (keyof FieldState)[];
meta?: (keyof MetaState)[];
sign?: (keyof SignState)[];
};
};
}
export type TransactionAction =

View File

@ -1,35 +0,0 @@
import * as interfaces from './actionTypes';
import { TypeKeys } from './constants';
export type TFetchTransactionData = typeof fetchTransactionData;
export function fetchTransactionData(txhash: string): interfaces.FetchTransactionDataAction {
return {
type: TypeKeys.TRANSACTIONS_FETCH_TRANSACTION_DATA,
payload: txhash
};
}
export type TSetTransactionData = typeof setTransactionData;
export function setTransactionData(
payload: interfaces.SetTransactionDataAction['payload']
): interfaces.SetTransactionDataAction {
return {
type: TypeKeys.TRANSACTIONS_SET_TRANSACTION_DATA,
payload
};
}
export type TResetTransactionData = typeof resetTransactionData;
export function resetTransactionData(): interfaces.ResetTransactionDataAction {
return { type: TypeKeys.TRANSACTIONS_RESET_TRANSACTION_DATA };
}
export type TAddRecentTransaction = typeof addRecentTransaction;
export function addRecentTransaction(
payload: interfaces.AddRecentTransactionAction['payload']
): interfaces.AddRecentTransactionAction {
return {
type: TypeKeys.TRANSACTIONS_ADD_RECENT_TRANSACTION,
payload
};
}

View File

@ -1,33 +0,0 @@
import { TypeKeys } from './constants';
import { SavedTransaction, TransactionData, TransactionReceipt } from 'types/transactions';
export interface FetchTransactionDataAction {
type: TypeKeys.TRANSACTIONS_FETCH_TRANSACTION_DATA;
payload: string;
}
export interface SetTransactionDataAction {
type: TypeKeys.TRANSACTIONS_SET_TRANSACTION_DATA;
payload: {
txhash: string;
data: TransactionData | null;
receipt: TransactionReceipt | null;
error: string | null;
};
}
export interface ResetTransactionDataAction {
type: TypeKeys.TRANSACTIONS_RESET_TRANSACTION_DATA;
}
export interface AddRecentTransactionAction {
type: TypeKeys.TRANSACTIONS_ADD_RECENT_TRANSACTION;
payload: SavedTransaction;
}
/*** Union Type ***/
export type TransactionsAction =
| FetchTransactionDataAction
| SetTransactionDataAction
| ResetTransactionDataAction
| AddRecentTransactionAction;

View File

@ -1,7 +0,0 @@
export enum TypeKeys {
TRANSACTIONS_FETCH_TRANSACTION_DATA = 'TRANSACTIONS_FETCH_TRANSACTION_DATA',
TRANSACTIONS_SET_TRANSACTION_DATA = 'TRANSACTIONS_SET_TRANSACTION_DATA',
TRANSACTIONS_SET_TRANSACTION_ERROR = 'TRANSACTIONS_SET_TRANSACTION_ERROR',
TRANSACTIONS_RESET_TRANSACTION_DATA = 'TRANSACTIONS_RESET_TRANSACTION_DATA',
TRANSACTIONS_ADD_RECENT_TRANSACTION = 'TRANSACTIONS_ADD_RECENT_TRANSACTION'
}

View File

@ -1,3 +0,0 @@
export * from './actionCreators';
export * from './actionTypes';
export * from './constants';

View File

@ -29,14 +29,10 @@ const repOptions = {
name: 'Augur'
};
export interface MappedRates {
[key: string]: any;
}
export function getAllRates() {
const mappedRates: MappedRates = {};
const mappedRates = {};
return _getAllRates().then(bityRates => {
bityRates.objects.forEach((each: any) => {
bityRates.objects.forEach(each => {
const pairName = each.pair;
const from = { id: pairName.substring(0, 3) };
const to = { id: pairName.substring(3, 6) };

View File

@ -1,88 +0,0 @@
import { checkHttpStatus, parseJSON } from './utils';
import { Omit } from 'react-redux';
const MAX_GAS_FAST = 250;
interface RawGasEstimates {
safeLow: number;
standard: number;
fast: number;
fastest: number;
block_time: number;
blockNum: number;
}
export interface GasEstimates {
safeLow: number;
standard: number;
fast: number;
fastest: number;
time: number;
chainId: number;
isDefault: boolean;
}
interface GasExpressResponse {
block_time: number;
blockNum: number;
fast: number;
fastest: number;
safeLow: number;
standard: number;
}
export function fetchGasEstimates(): Promise<GasEstimates> {
return fetch('https://dev.blockscale.net/api/gasexpress.json', {
mode: 'cors'
})
.then(checkHttpStatus)
.then(parseJSON)
.then((res: GasExpressResponse) => {
// Make sure it looks like a raw gas estimate, and it has valid values
const keys: (keyof Omit<GasExpressResponse, 'block_time' | 'blockNum'>)[] = [
'safeLow',
'standard',
'fast',
'fastest'
];
keys.forEach(key => {
if (typeof res[key] !== 'number') {
throw new Error(
`Gas estimate API has invalid shape: Expected numeric key '${key}' in response, got '${
res[key]
}' instead`
);
}
});
// Make sure the estimate isn't totally crazy
const estimateRes = res as RawGasEstimates;
if (estimateRes.fast > MAX_GAS_FAST) {
throw new Error(
`Gas estimate response estimate too high: Max fast is ${MAX_GAS_FAST}, was given ${
estimateRes.fast
}`
);
}
if (
estimateRes.safeLow > estimateRes.standard ||
estimateRes.standard > estimateRes.fast ||
estimateRes.fast > estimateRes.fastest
) {
throw new Error(
`Gas esimates are in illogical order: should be safeLow < standard < fast < fastest, received ${
estimateRes.safeLow
} < ${estimateRes.standard} < ${estimateRes.fast} < ${estimateRes.fastest}`
);
}
return estimateRes;
})
.then((res: RawGasEstimates) => ({
...res,
time: Date.now(),
chainId: 1,
isDefault: false
}));
}

View File

@ -28,44 +28,6 @@ export const SHAPESHIFT_TOKEN_WHITELIST = [
];
export const SHAPESHIFT_WHITELIST = [...SHAPESHIFT_TOKEN_WHITELIST, 'ETH', 'ETC', 'BTC'];
interface IPairData {
limit: number;
maxLimit: number;
min: number;
minerFee: number;
pair: string;
rate: string;
}
interface IExtraPairData {
status: string;
image: string;
name: string;
}
interface IAvailablePairData {
[pairName: string]: IExtraPairData;
}
interface ShapeshiftMarketInfo {
rate: string;
limit: number;
pair: string;
maxLimit: number;
min: number;
minerFee: number;
}
interface TokenMap {
[pairName: string]: {
id: string;
rate: string;
limit: number;
min: number;
options: (IExtraPairData & { id: string })[];
};
}
class ShapeshiftService {
public whitelist = SHAPESHIFT_WHITELIST;
private url = SHAPESHIFT_BASE_URL;
@ -74,18 +36,13 @@ class ShapeshiftService {
'Content-Type': 'application/json'
};
public checkStatus(address: string) {
public checkStatus(address) {
return fetch(`${this.url}/txStat/${address}`)
.then(checkHttpStatus)
.then(parseJSON);
}
public sendAmount(
withdrawal: string,
originKind: string,
destinationKind: string,
destinationAmount: number
) {
public sendAmount(withdrawal, originKind, destinationKind, destinationAmount) {
const pair = `${originKind.toLowerCase()}_${destinationKind.toLowerCase()}`;
return fetch(`${this.url}/sendamount`, {
@ -124,7 +81,7 @@ class ShapeshiftService {
return mappedRates;
};
private getPairRates(marketInfo: ShapeshiftMarketInfo[]) {
private getPairRates(marketInfo) {
const filteredMarketInfo = marketInfo.filter(obj => {
const { pair } = obj;
const pairArr = pair.split('_');
@ -140,7 +97,7 @@ class ShapeshiftService {
return pairRates;
}
private async checkAvl(pairRates: IPairData[]) {
private async checkAvl(pairRates) {
const avlCoins = await this.getAvlCoins();
const mapAvl = pairRates.map(p => {
const { pair } = p;
@ -164,8 +121,7 @@ class ShapeshiftService {
};
}
});
const filered = mapAvl.filter(v => v);
return filered as (IPairData & IAvailablePairData)[];
return mapAvl;
}
private getAvlCoins() {
@ -174,7 +130,7 @@ class ShapeshiftService {
.then(parseJSON);
}
private getSinglePairRate(pair: string) {
private getSinglePairRate(pair) {
return fetch(`${this.url}/rate/${pair}`)
.then(checkHttpStatus)
.then(parseJSON);
@ -186,12 +142,12 @@ class ShapeshiftService {
.then(parseJSON);
}
private isWhitelisted(coin: string) {
private isWhitelisted(coin) {
return this.whitelist.includes(coin);
}
private mapMarketInfo(marketInfo: (IPairData & IAvailablePairData)[]) {
const tokenMap: TokenMap = {};
private mapMarketInfo(marketInfo) {
const tokenMap = {};
marketInfo.forEach(m => {
const originKind = m.pair.substring(0, 3);
const destinationKind = m.pair.substring(4, 7);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View File

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version='1.1' xmlns='http://www.w3.org/2000/svg' x='0px' y='0px' width='20px' height='20px' viewBox='0 0 79.536 79.536' style='enable-background:new 0 0 79.536 79.536;' xml:space='preserve'><path fill='#999' d='M39.769,0C17.8,0,0,17.8,0,39.768c0,21.965,17.8,39.768,39.769,39.768 c21.965,0,39.768-17.803,39.768-39.768C79.536,17.8,61.733,0,39.769,0z M34.142,58.513L15.397,39.768l7.498-7.498l11.247,11.247 l22.497-22.493l7.498,7.498L34.142,58.513z'/></svg>

After

Width:  |  Height:  |  Size: 602 B

View File

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="20px" height="20px" viewBox="0 0 528.899 528.899" style="enable-background:new 0 0 528.899 528.899;" xml:space="preserve"><path fill="#21a4ce" d="M328.883,89.125l107.59,107.589l-272.34,272.34L56.604,361.465L328.883,89.125z M518.113,63.177l-47.981-47.981 c-18.543-18.543-48.653-18.543-67.259,0l-45.961,45.961l107.59,107.59l53.611-53.611 C532.495,100.753,532.495,77.559,518.113,63.177z M0.3,512.69c-1.958,8.812,5.998,16.708,14.811,14.565l119.891-29.069 L27.473,390.597L0.3,512.69z"/></svg>

After

Width:  |  Height:  |  Size: 761 B

View File

@ -0,0 +1 @@
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 92 92"><path fill="#ECECEC" d="M45.386.004C19.983.344-.333 21.215.005 46.619c.34 25.393 21.209 45.715 46.611 45.377 25.398-.342 45.718-21.213 45.38-46.615-.34-25.395-21.21-45.716-46.61-45.377zM45.25 74l-.254-.004c-3.912-.116-6.67-2.998-6.559-6.852.109-3.788 2.934-6.538 6.717-6.538l.227.004c4.021.119 6.748 2.972 6.635 6.937C51.904 71.346 49.123 74 45.25 74zm16.455-32.659c-.92 1.307-2.943 2.93-5.492 4.916l-2.807 1.938c-1.541 1.198-2.471 2.325-2.82 3.434-.275.873-.41 1.104-.434 2.88l-.004.451H39.43l.031-.907c.131-3.728.223-5.921 1.768-7.733 2.424-2.846 7.771-6.289 7.998-6.435.766-.577 1.412-1.234 1.893-1.936 1.125-1.551 1.623-2.772 1.623-3.972a7.74 7.74 0 0 0-1.471-4.576c-.939-1.323-2.723-1.993-5.303-1.993-2.559 0-4.311.812-5.359 2.478-1.078 1.713-1.623 3.512-1.623 5.35v.457H27.936l.02-.477c.285-6.769 2.701-11.643 7.178-14.487C37.947 18.918 41.447 18 45.531 18c5.346 0 9.859 1.299 13.412 3.861 3.6 2.596 5.426 6.484 5.426 11.556 0 2.837-.896 5.502-2.664 7.924z"/></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1 +1 @@
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 92 92"><path fill="#007896" d="M45.386.004C19.983.344-.333 21.215.005 46.619c.34 25.393 21.209 45.715 46.611 45.377 25.398-.342 45.718-21.213 45.38-46.615-.34-25.395-21.21-45.716-46.61-45.377zM45.25 74l-.254-.004c-3.912-.116-6.67-2.998-6.559-6.852.109-3.788 2.934-6.538 6.717-6.538l.227.004c4.021.119 6.748 2.972 6.635 6.937C51.904 71.346 49.123 74 45.25 74zm16.455-32.659c-.92 1.307-2.943 2.93-5.492 4.916l-2.807 1.938c-1.541 1.198-2.471 2.325-2.82 3.434-.275.873-.41 1.104-.434 2.88l-.004.451H39.43l.031-.907c.131-3.728.223-5.921 1.768-7.733 2.424-2.846 7.771-6.289 7.998-6.435.766-.577 1.412-1.234 1.893-1.936 1.125-1.551 1.623-2.772 1.623-3.972a7.74 7.74 0 0 0-1.471-4.576c-.939-1.323-2.723-1.993-5.303-1.993-2.559 0-4.311.812-5.359 2.478-1.078 1.713-1.623 3.512-1.623 5.35v.457H27.936l.02-.477c.285-6.769 2.701-11.643 7.178-14.487C37.947 18.918 41.447 18 45.531 18c5.346 0 9.859 1.299 13.412 3.861 3.6 2.596 5.426 6.484 5.426 11.556 0 2.837-.896 5.502-2.664 7.924z"/></svg>
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 92 92"><path fill="#0e97c0" d="M45.386.004C19.983.344-.333 21.215.005 46.619c.34 25.393 21.209 45.715 46.611 45.377 25.398-.342 45.718-21.213 45.38-46.615-.34-25.395-21.21-45.716-46.61-45.377zM45.25 74l-.254-.004c-3.912-.116-6.67-2.998-6.559-6.852.109-3.788 2.934-6.538 6.717-6.538l.227.004c4.021.119 6.748 2.972 6.635 6.937C51.904 71.346 49.123 74 45.25 74zm16.455-32.659c-.92 1.307-2.943 2.93-5.492 4.916l-2.807 1.938c-1.541 1.198-2.471 2.325-2.82 3.434-.275.873-.41 1.104-.434 2.88l-.004.451H39.43l.031-.907c.131-3.728.223-5.921 1.768-7.733 2.424-2.846 7.771-6.289 7.998-6.435.766-.577 1.412-1.234 1.893-1.936 1.125-1.551 1.623-2.772 1.623-3.972a7.74 7.74 0 0 0-1.471-4.576c-.939-1.323-2.723-1.993-5.303-1.993-2.559 0-4.311.812-5.359 2.478-1.078 1.713-1.623 3.512-1.623 5.35v.457H27.936l.02-.477c.285-6.769 2.701-11.643 7.178-14.487C37.947 18.918 41.447 18 45.531 18c5.346 0 9.859 1.299 13.412 3.861 3.6 2.596 5.426 6.484 5.426 11.556 0 2.837-.896 5.502-2.664 7.924z"/></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1 @@
<svg version="1.1" width="20px" height="20px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 92 92" style="enable-background:new 0 0 92 92;" xml:space="preserve"><path fill="#2bb2dd" d="M45.386,0.004C19.983,0.344-0.333,21.215,0.005,46.619c0.34,25.393,21.209,45.715,46.611,45.377 c25.398-0.342,45.718-21.213,45.38-46.615C91.656,19.986,70.786-0.335,45.386,0.004z M45.25,74l-0.254-0.004 c-3.912-0.116-6.67-2.998-6.559-6.852c0.109-3.788,2.934-6.538,6.717-6.538l0.227,0.004c4.021,0.119,6.748,2.972,6.635,6.937 C51.904,71.346,49.123,74,45.25,74z M61.705,41.341c-0.92,1.307-2.943,2.93-5.492,4.916l-2.807,1.938 c-1.541,1.198-2.471,2.325-2.82,3.434c-0.275,0.873-0.41,1.104-0.434,2.88l-0.004,0.451H39.43l0.031-0.907 c0.131-3.728,0.223-5.921,1.768-7.733c2.424-2.846,7.771-6.289,7.998-6.435c0.766-0.577,1.412-1.234,1.893-1.936 c1.125-1.551,1.623-2.772,1.623-3.972c0-1.665-0.494-3.205-1.471-4.576c-0.939-1.323-2.723-1.993-5.303-1.993 c-2.559,0-4.311,0.812-5.359,2.478c-1.078,1.713-1.623,3.512-1.623,5.35v0.457H27.936l0.02-0.477 c0.285-6.769,2.701-11.643,7.178-14.487C37.947,18.918,41.447,18,45.531,18c5.346,0,9.859,1.299,13.412,3.861 c3.6,2.596,5.426,6.484,5.426,11.556C64.369,36.254,63.473,38.919,61.705,41.341z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version='1.1' xmlns='http://www.w3.org/2000/svg' x='0px' y='0px' width='20px' height='20px' viewBox='0 0 511.626 511.626' style='enable-background:new 0 0 511.626 511.626;' xml:space='preserve'><path fill='#f0ad4e' d='M505.918,236.117c-26.651-43.587-62.485-78.609-107.497-105.065c-45.015-26.457-92.549-39.687-142.608-39.687 c-50.059,0-97.595,13.225-142.61,39.687C68.187,157.508,32.355,192.53,5.708,236.117C1.903,242.778,0,249.345,0,255.818 c0,6.473,1.903,13.04,5.708,19.699c26.647,43.589,62.479,78.614,107.495,105.064c45.015,26.46,92.551,39.68,142.61,39.68 c50.06,0,97.594-13.176,142.608-39.536c45.012-26.361,80.852-61.432,107.497-105.208c3.806-6.659,5.708-13.223,5.708-19.699 C511.626,249.345,509.724,242.778,505.918,236.117z M194.568,158.03c17.034-17.034,37.447-25.554,61.242-25.554 c3.805,0,7.043,1.336,9.709,3.999c2.662,2.664,4,5.901,4,9.707c0,3.809-1.338,7.044-3.994,9.704 c-2.662,2.667-5.902,3.999-9.708,3.999c-16.368,0-30.362,5.808-41.971,17.416c-11.613,11.615-17.416,25.603-17.416,41.971 c0,3.811-1.336,7.044-3.999,9.71c-2.667,2.668-5.901,3.999-9.707,3.999c-3.809,0-7.044-1.334-9.71-3.999 c-2.667-2.666-3.999-5.903-3.999-9.71C169.015,195.482,177.535,175.065,194.568,158.03z M379.867,349.04 c-38.164,23.12-79.514,34.687-124.054,34.687c-44.539,0-85.889-11.56-124.051-34.687s-69.901-54.2-95.215-93.222 c28.931-44.921,65.19-78.518,108.777-100.783c-11.61,19.792-17.417,41.207-17.417,64.236c0,35.216,12.517,65.329,37.544,90.362 s55.151,37.544,90.362,37.544c35.214,0,65.329-12.518,90.362-37.544s37.545-55.146,37.545-90.362 c0-23.029-5.808-44.447-17.419-64.236c43.585,22.265,79.846,55.865,108.776,100.783C449.767,294.84,418.031,325.913,379.867,349.04 z'/></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version='1.1' xmlns='http://www.w3.org/2000/svg' width='20px' height='20px'
xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 27.965 27.965'
style='enable-background:new 0 0 27.965 27.965;'>
<path fill='#999'
d='M13.98,0C6.259,0,0,6.261,0,13.983c0,7.721,6.259,13.982,13.98,13.982c7.725,0,13.985-6.262,13.985-13.982 C27.965,6.261,21.705,0,13.98,0z M19.992,17.769l-2.227,2.224c0,0-3.523-3.78-3.786-3.78c-0.259,0-3.783,3.78-3.783,3.78 l-2.228-2.224c0,0,3.784-3.472,3.784-3.781c0-0.314-3.784-3.787-3.784-3.787l2.228-2.229c0,0,3.553,3.782,3.783,3.782 c0.232,0,3.786-3.782,3.786-3.782l2.227,2.229c0,0-3.785,3.523-3.785,3.787C16.207,14.239,19.992,17.769,19.992,17.769z'/>
</svg>

After

Width:  |  Height:  |  Size: 866 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -8,7 +8,7 @@
<g id="Artboard" fill-rule="nonzero">
<g id="logo-mycrypto">
<g id="Group">
<circle id="Oval" fill="#007896" cx="120.18" cy="121" r="120.18"></circle>
<circle id="Oval" fill="#0e97c0" cx="120.18" cy="121" r="120.18"></circle>
<g transform="translate(39.000000, 51.000000)" fill="#FFFFFF" id="Shape">
<path d="M93.7,100.26 C90.4608521,103.553832 86.034676,105.408954 81.415,105.408954 C76.795324,105.408954 72.3691479,103.553832 69.13,100.26 L53.47,84.43 C51.4545763,82.3796602 48.700035,81.2248104 45.825,81.2248104 C42.949965,81.2248104 40.1954237,82.3796602 38.18,84.43 C31.3962777,91.3322169 31.3962777,102.397783 38.18,109.3 L69.18,140.59 C72.4191479,143.883832 76.845324,145.738954 81.465,145.738954 C86.084676,145.738954 90.5108521,143.883832 93.75,140.59 L124.67,109.26 C131.453722,102.357783 131.453722,91.2922169 124.67,84.39 C122.654576,82.3396602 119.900035,81.1848104 117.025,81.1848104 C114.149965,81.1848104 111.395424,82.3396602 109.38,84.39 L93.7,100.26 Z"></path>
<g>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,97 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="81px" height="120px" viewBox="0 0 81 120" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 48.2 (47327) - http://www.bohemiancoding.com/sketch -->
<title>Artboard</title>
<desc>Created with Sketch.</desc>
<defs>
<linearGradient x1="100.099854%" y1="-16.122731%" x2="44.1579795%" y2="77.6511455%" id="linearGradient-1">
<stop stop-color="#2B415B" offset="13.45%"></stop>
<stop stop-color="#3B5676" offset="37.62%"></stop>
<stop stop-color="#54769E" offset="69.23%"></stop>
<stop stop-color="#52749B" offset="79.01%"></stop>
<stop stop-color="#4D6C92" offset="86.14%"></stop>
<stop stop-color="#436082" offset="92.44%"></stop>
<stop stop-color="#364F6C" offset="98.22%"></stop>
<stop stop-color="#314863" offset="100%"></stop>
</linearGradient>
<linearGradient x1="99.7887646%" y1="61.4941149%" x2="-4.60729499%" y2="13.3460499%" id="linearGradient-2">
<stop stop-color="#54769E" offset="0%"></stop>
<stop stop-color="#53749C" offset="48.02%"></stop>
<stop stop-color="#4F6F95" offset="68.78%"></stop>
<stop stop-color="#486588" offset="84.23%"></stop>
<stop stop-color="#435F80" offset="90.95%"></stop>
</linearGradient>
<linearGradient x1="725.856983%" y1="50.0229457%" x2="-347.124022%" y2="50.0229457%" id="linearGradient-3">
<stop stop-color="#20344C" offset="25.39%"></stop>
<stop stop-color="#273D57" offset="40.72%"></stop>
<stop stop-color="#395373" offset="67.33%"></stop>
<stop stop-color="#54769E" offset="100%"></stop>
</linearGradient>
<linearGradient x1="-653.788268%" y1="50.0214562%" x2="455.494413%" y2="50.0214562%" id="linearGradient-4">
<stop stop-color="#54769E" offset="25.39%"></stop>
<stop stop-color="#4D6E93" offset="41.33%"></stop>
<stop stop-color="#3C5777" offset="68.97%"></stop>
<stop stop-color="#233850" offset="100%"></stop>
</linearGradient>
<linearGradient x1="50.0370086%" y1="-209.335792%" x2="49.9575834%" y2="235.965027%" id="linearGradient-5">
<stop stop-color="#54769E" offset="0.6545247%"></stop>
<stop stop-color="#507198" offset="19.93%"></stop>
<stop stop-color="#466488" offset="45.02%"></stop>
<stop stop-color="#354F6D" offset="73.18%"></stop>
<stop stop-color="#21354D" offset="100%"></stop>
</linearGradient>
<linearGradient x1="163.859644%" y1="-95.5767241%" x2="-53.1396713%" y2="173.049483%" id="linearGradient-6">
<stop stop-color="#54769E" offset="25.39%"></stop>
<stop stop-color="#4D6E93" offset="41.02%"></stop>
<stop stop-color="#3C5777" offset="68.13%"></stop>
<stop stop-color="#22364E" offset="100%"></stop>
</linearGradient>
<linearGradient x1="-44.1116757%" y1="-60.1463542%" x2="137.687762%" y2="146.957292%" id="linearGradient-7">
<stop stop-color="#54769E" offset="25.39%"></stop>
<stop stop-color="#4D6E93" offset="41.02%"></stop>
<stop stop-color="#3C5777" offset="68.13%"></stop>
<stop stop-color="#22364E" offset="100%"></stop>
</linearGradient>
<linearGradient x1="-1.43584837%" y1="31.6007047%" x2="127.701745%" y2="103.798097%" id="linearGradient-8">
<stop stop-color="#54769E" offset="26.64%"></stop>
<stop stop-color="#425E7F" offset="100%"></stop>
</linearGradient>
<linearGradient x1="-71.276129%" y1="-65.3137535%" x2="149.174581%" y2="96.3311507%" id="linearGradient-9">
<stop stop-color="#54769E" stop-opacity="0" offset="46.09%"></stop>
<stop stop-color="#52739A" stop-opacity="0.2156" offset="56.99%"></stop>
<stop stop-color="#4A698E" stop-opacity="0.4266" offset="67.64%"></stop>
<stop stop-color="#3D597B" stop-opacity="0.6356" offset="78.2%"></stop>
<stop stop-color="#2C435F" stop-opacity="0.8422" offset="88.63%"></stop>
<stop stop-color="#1B2E45" offset="96.61%"></stop>
</linearGradient>
<linearGradient x1="50.309375%" y1="295.997443%" x2="50.309375%" y2="-124.649242%" id="linearGradient-10">
<stop stop-color="#54769E" offset="25.39%"></stop>
<stop stop-color="#4D6E93" offset="41.02%"></stop>
<stop stop-color="#3C5777" offset="68.13%"></stop>
<stop stop-color="#22364E" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Artboard" fill-rule="nonzero">
<g id="logo-shapeshift">
<polygon id="Shape" fill="#273C51" points="75.9045553 29.0113736 81 0.0349956255 59.7045553 8.88888889 36.3006508 8.88888889 15.0052061 0 20.1357918 29.0113736 15.3214751 45.1793526 19.8546638 48.0139983 0 65.3718285 0 81.67979 22.7010846 112.825897 44.1019523 119.965004 44.1370933 120 60.8642082 111.461067 60.8993492 111.426072 60.8993492 98.7926509 51.4112798 93.6132983 51.4112798 93.6132983 51.4112798 93.6132983 66.3110629 54.1032371 66.2056399 54.1032371 80.683731 45.1793526"></polygon>
<g id="Group">
<polygon id="Shape" fill="url(#linearGradient-1)" points="34.2584416 35.3372093 0 65.2325581 47.7233766 92.5465116 47.8987013 36.244186"></polygon>
<polygon id="Shape" fill="#466284" points="29.3844156 53.8255814 47.7584416 102.697674 47.8987013 56.5465116"></polygon>
<polygon id="Shape" fill="#354D6A" points="66.1675325 54 47.7584416 102.697674 47.8987013 56.5465116"></polygon>
<polygon id="Shape" fill="url(#linearGradient-2)" points="80.8246753 0.104651163 62.5558442 9.6627907 47.9337662 12.8372093 33.1714286 9.6627907 14.9727273 0.0697674419 21.2493506 28.9186047 15.2883117 45.1046512 36.187013 58.0116279 47.7935065 70.5697674 47.7935065 70.6744186 47.8636364 70.6046512 47.9337662 70.6744186 47.9337662 70.5697674 59.5402597 58.0116279 80.5090909 45.1046512 74.5480519 28.9534884"></polygon>
<polygon id="Shape" fill="url(#linearGradient-3)" points="80.8246753 0.104651163 75.7402597 28.9883721 80.5090909 45.1046512 74.5480519 28.9534884"></polygon>
<polygon id="Shape" fill="url(#linearGradient-4)" points="14.9727273 0.0697674419 20.0922078 28.9883721 15.2883117 45.1046512 21.2493506 28.9186047"></polygon>
<polygon id="Shape" fill="url(#linearGradient-5)" points="14.9727273 0.0697674419 36.2220779 8.93023256 59.5753247 8.93023256 80.8246753 0.104651163 62.5558442 9.6627907 47.9337662 12.8372093 33.1714286 9.6627907"></polygon>
<polygon id="Shape" fill="url(#linearGradient-6)" points="21.2493506 28.9186047 20.1974026 31.8139535 42.2532468 11.5813953"></polygon>
<polygon id="Shape" fill="url(#linearGradient-7)" points="74.5480519 28.9534884 53.6493506 11.5813953 75.5649351 31.6744186"></polygon>
<polygon id="Shape" fill="url(#linearGradient-8)" points="0 65.2325581 51.3 93.3837209 57.787013 109.534884 44.0415584 114.732558 22.6519481 112.534884 0 81.4883721"></polygon>
<polygon id="Shape" fill="#FFFFFF" points="42.4636364 88.5348837 22.7220779 112.465116 22.6519481 112.534884 44.0064935 119.651163 44.0415584 119.686047 60.7324675 111.174419 60.7675325 111.139535 60.7675325 98.5465116"></polygon>
<polygon id="Shape" fill="url(#linearGradient-9)" points="74.5480519 28.9534884 80.8246753 0.104651163 62.5558442 9.6627907 53.6493506 11.5813953"></polygon>
<polygon id="Shape" fill="#FFFFFF" points="47.8987013 70.6744186 42.112987 64.3604651 47.8987013 58.0116279 53.7194805 64.3604651"></polygon>
<polygon id="Shape" fill="url(#linearGradient-10)" points="47.3376623 12.6976744 47.9337662 12.8372093 48.4597403 12.7325581 47.8987013 49.5348837"></polygon>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -54,7 +54,7 @@
<path d="M82.77,744.06 L87.55,710.06 C87.8071361,708.226119 86.9908966,706.407071 85.45,705.38 C78.3717357,700.699197 75.198423,691.93208 77.6408657,683.805198 C80.0833084,675.678315 87.5640273,670.113147 96.05,670.11 C96.64,670.11 97.2,670.23 97.78,670.28 C88.9158298,664.439589 76.9954116,666.89083 71.1550005,675.755 C65.3145894,684.61917 67.7658301,696.539589 76.63,702.38 C78.1708966,703.407071 78.9871361,705.226119 78.73,707.06 L73.53,744.06 L82.77,744.06 Z" id="Shape" fill="#000000" opacity="0.1"></path>
<g id="mycrypto__circ__blue-on-navy__64" transform="translate(116.000000, 0.000000)">
<g id="Oval">
<use fill="#007896" fill-rule="evenodd" xlink:href="#path-1"></use>
<use fill="#0E97C0" fill-rule="evenodd" xlink:href="#path-1"></use>
<circle stroke="#000000" stroke-width="10" cx="145" cy="145" r="140"></circle>
</g>
<g id="Shape">
@ -69,4 +69,4 @@
</g>
</g>
</g>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -32,7 +32,7 @@
<rect id="Rectangle-path" fill="#FFCE00" x="40.72" y="256.52" width="16" height="48"></rect>
</g>
<g id="mycrypto__circ__blue-on-navy__64" transform="translate(216.000000, 191.000000)">
<circle id="Oval" fill="#007896" cx="37" cy="37" r="37"></circle>
<circle id="Oval" fill="#0E97C0" cx="37" cy="37" r="37"></circle>
<g id="Shape">
<use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-1"></use>
<path stroke="#000000" stroke-width="2" d="M48.7644965,40.0113785 C49.7178355,40.010501 50.6345076,40.3752222 51.3145109,41.0314555 C53.5618297,43.2182135 53.5618297,46.7390341 51.3110373,48.9291558 L41.5069096,58.3771804 C40.4445637,59.4168045 38.9938635,60.0003162 37.4823951,59.9999999 C35.9705083,60.0003162 34.5198081,59.4168045 33.4616659,58.3812702 L23.6854891,48.9257921 C21.4381703,46.7390341 21.4381703,43.2182135 23.6838532,41.033051 C24.3665268,40.3657303 25.2975124,39.9945561 26.2579466,40.0000451 C27.2198046,39.9987497 28.1441246,40.3696137 28.8202797,41.0305404 L33.7601132,45.8246431 C34.7441958,46.7780599 36.0942246,47.317442 37.505938,47.317442 C38.9176514,47.317442 40.2676802,46.7780599 41.2528603,45.8235816 L46.2009116,41.0443696 C46.8793196,40.3812496 47.8031089,40.0104213 48.7644965,40.0113785 Z"></path>
@ -44,4 +44,4 @@
</g>
</g>
</g>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 67 KiB

View File

@ -13,7 +13,7 @@
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<circle stroke="#007896" stroke-width="20" cx="170" cy="170" r="160"></circle>
<circle stroke="#0E97C0" stroke-width="20" cx="170" cy="170" r="160"></circle>
<rect id="Rectangle" fill="#FFE14D" mask="url(#mask-2)" x="-1.13333333" y="1.13333333" width="173.4" height="340"></rect>
<rect id="Rectangle" fill="#FFCC33" mask="url(#mask-2)" x="171.133333" y="1.13333333" width="173.4" height="340"></rect>
<circle id="Oval-2" stroke="#333333" stroke-width="20" mask="url(#mask-2)" cx="170" cy="170" r="160"></circle>
@ -23,7 +23,7 @@
<mask id="mask-4" fill="white">
<use xlink:href="#path-3"></use>
</mask>
<circle stroke="#007896" stroke-width="20" cx="170" cy="170" r="160"></circle>
<circle stroke="#0E97C0" stroke-width="20" cx="170" cy="170" r="160"></circle>
<rect id="Rectangle" fill="#6EA6E8" mask="url(#mask-4)" x="-1.13333333" y="1.13333333" width="173.4" height="340"></rect>
<rect id="Rectangle" fill="#5C9BE4" mask="url(#mask-4)" x="171.133333" y="1.13333333" width="173.4" height="340"></rect>
<circle id="Oval-2" stroke="#333333" stroke-width="20" mask="url(#mask-4)" cx="170" cy="170" r="160"></circle>
@ -41,4 +41,4 @@
</g>
</g>
</g>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="330px" height="330px" viewBox="0 0 330 330" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 46 (44423) - http://www.bohemiancoding.com/sketch -->
<title>Group 3</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group-3">
<circle id="Oval-2" fill="#000000" cx="164.912047" cy="164.912047" r="164.912047"></circle>
<g id="Group-2" transform="translate(164.934365, 164.978810) rotate(-315.000000) translate(-164.934365, -164.978810) translate(65.924073, 66.000110)" fill="#FFFFFF">
<g id="Group">
<path d="M20.5676823,0 L75.3319399,0 C86.6911571,-2.08665436e-15 95.8996221,9.20846501 95.8996221,20.5676823 L95.8996221,75.3319399 C95.8996221,86.6911571 86.6911571,95.8996221 75.3319399,95.8996221 L20.5676823,95.8996221 C9.20846501,95.8996221 1.3911029e-15,86.6911571 0,75.3319399 L0,20.5676823 C-1.3911029e-15,9.20846501 9.20846501,2.08665436e-15 20.5676823,0 Z M47.9498111,65.9309902 C57.8805421,65.9309902 65.9309902,57.8805421 65.9309902,47.9498111 C65.9309902,38.01908 57.8805421,29.9686319 47.9498111,29.9686319 C38.01908,29.9686319 29.9686319,38.01908 29.9686319,47.9498111 C29.9686319,57.8805421 38.01908,65.9309902 47.9498111,65.9309902 Z" id="Combined-Shape"></path>
<path d="M122.460048,7.71386383 C115.360537,7.71386383 109.605246,13.4691545 109.605246,20.5686652 L109.605246,75.3329229 C109.605246,82.4324336 115.360537,88.1877243 122.460048,88.1877243 L177.224305,88.1877243 C184.323816,88.1877243 190.079107,82.4324336 190.079107,75.3329229 L190.079107,20.5686652 C190.079107,13.4691545 184.323816,7.71386383 177.224305,7.71386383 L122.460048,7.71386383 Z M122.460048,0.000982982783 L177.224305,0.000982982783 C188.583523,0.000982982783 197.791988,9.20944799 197.791988,20.5686652 L197.791988,75.3329229 C197.791988,86.6921401 188.583523,95.9006051 177.224305,95.9006051 L122.460048,95.9006051 C111.100831,95.9006051 101.892366,86.6921401 101.892366,75.3329229 L101.892366,20.5686652 C101.892366,9.20944799 111.100831,0.000982982783 122.460048,0.000982982783 Z" id="Combined-Shape" fill-rule="nonzero"></path>
<circle id="Oval" cx="149.842177" cy="47.9507941" r="17.9811792"></circle>
<path d="M20.5676823,101.893349 L75.3319399,101.893349 C86.6911571,101.893349 95.8996221,111.101814 95.8996221,122.461031 L95.8996221,177.225288 C95.8996221,188.584506 86.6911571,197.792971 75.3319399,197.792971 L20.5676823,197.792971 C9.20846501,197.792971 1.3911029e-15,188.584506 0,177.225288 L0,122.461031 C-1.3911029e-15,111.101814 9.20846501,101.893349 20.5676823,101.893349 Z M47.9498111,167.824339 C57.8805421,167.824339 65.9309902,159.773891 65.9309902,149.84316 C65.9309902,139.912429 57.8805421,131.86198 47.9498111,131.86198 C38.01908,131.86198 29.9686319,139.912429 29.9686319,149.84316 C29.9686319,159.773891 38.01908,167.824339 47.9498111,167.824339 Z" id="Combined-Shape"></path>
<path d="M122.461031,101.893349 L177.225288,101.893349 C188.584506,101.893349 197.792971,111.101814 197.792971,122.461031 L197.792971,177.225288 C197.792971,188.584506 188.584506,197.792971 177.225288,197.792971 L122.461031,197.792971 C111.101814,197.792971 101.893349,188.584506 101.893349,177.225288 L101.893349,122.461031 C101.893349,111.101814 111.101814,101.893349 122.461031,101.893349 Z M149.84316,167.824339 C159.773891,167.824339 167.824339,159.773891 167.824339,149.84316 C167.824339,139.912429 159.773891,131.86198 149.84316,131.86198 C139.912429,131.86198 131.86198,139.912429 131.86198,149.84316 C131.86198,159.773891 139.912429,167.824339 149.84316,167.824339 Z" id="Combined-Shape"></path>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -0,0 +1,36 @@
// Mixins
// --------------------------------------------------
// Utilities
@import "mixins/hide-text.less";
@import "mixins/opacity.less";
@import "mixins/image.less";
@import "mixins/labels.less";
@import "mixins/reset-filter.less";
@import "mixins/resize.less";
@import "mixins/responsive-visibility.less";
@import "mixins/size.less";
@import "mixins/tab-focus.less";
@import "mixins/reset-text.less";
@import "mixins/text-emphasis.less";
@import "mixins/text-overflow.less";
@import "mixins/vendor-prefixes.less";
// Components
@import "mixins/alerts.less";
@import "mixins/buttons.less";
@import "mixins/panels.less";
@import "mixins/pagination.less";
@import "mixins/list-group.less";
@import "mixins/nav-divider.less";
@import "mixins/forms.less";
@import "mixins/progress-bar.less";
@import "mixins/table-row.less";
// Skins
@import "mixins/background-variant.less";
@import "mixins/border-radius.less";
@import "mixins/gradients.less";
// Layout
@import "mixins/clearfix.less";
@import "mixins/center-block.less";
@import "mixins/nav-vertical-align.less";
@import "mixins/grid-framework.less";
@import "mixins/grid.less";

View File

@ -0,0 +1,14 @@
// Alerts
.alert-variant(@background; @border; @text-color) {
background-color: @background;
border-color: @border;
color: @text-color;
hr {
border-top-color: darken(@border, 5%);
}
.alert-link {
color: darken(@text-color, 10%);
}
}

View File

@ -0,0 +1,9 @@
// Contextual backgrounds
.bg-variant(@color) {
background-color: @color;
a&:hover,
a&:focus {
background-color: darken(@color, 10%);
}
}

View File

@ -0,0 +1,21 @@
// Single side border-radius
.border-top-radius(@radius) {
border-top-right-radius: @radius;
border-top-left-radius: @radius;
}
.border-right-radius(@radius) {
border-bottom-right-radius: @radius;
border-top-right-radius: @radius;
}
.border-bottom-radius(@radius) {
border-bottom-right-radius: @radius;
border-bottom-left-radius: @radius;
}
.border-left-radius(@radius) {
border-bottom-left-radius: @radius;
border-top-left-radius: @radius;
}

View File

@ -0,0 +1,73 @@
// Button variants
//
// Easily pump out default styles, as well as :hover, :focus, :active,
// and disabled options for all buttons
.button-variant(@color; @background; @border) {
color: @color;
background-color: @background;
border-color: @border;
transition: all ease 250ms;
&:focus,
&.focus {
color: @color;
background-color: darken(@background, 5%);
border-color: darken(@border, 5%);
transition: all ease 250ms;
}
&:hover {
color: @color;
background-color: darken(@background, 5%);
border-color: darken(@border, 5%);
transition: all ease 250ms;
}
&:active,
&.active,
.open > .dropdown-toggle& {
color: @color;
background-color: darken(@background, 5%);
border-color: darken(@border, 5%);
transition: all ease 250ms;
&:hover,
&:focus,
&.focus {
color: @color;
background-color: darken(@background, 15%);
border-color: darken(@border, 15%);
transition: all ease 250ms;
}
}
&:active,
&.active,
.open > .dropdown-toggle& {
background-image: none;
}
&.disabled,
&[disabled],
fieldset[disabled] & {
&,
&:hover,
&:focus,
&.focus,
&:active,
&.active {
background-color: @background;
border-color: @border;
}
}
.badge {
color: @background;
background-color: @color;
}
}
// Button sizes
.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {
padding: @padding-vertical @padding-horizontal;
font-size: @font-size;
line-height: @line-height;
border-radius: @border-radius;
}

View File

@ -0,0 +1,7 @@
// Center-align a block level element
.center-block() {
display: block;
margin-left: auto;
margin-right: auto;
}

View File

@ -0,0 +1,22 @@
// Clearfix
//
// For modern browsers
// 1. The space content is one way to avoid an Opera bug when the
// contenteditable attribute is included anywhere else in the document.
// Otherwise it causes space to appear at the top and bottom of elements
// that are clearfixed.
// 2. The use of `table` rather than `block` is only necessary if using
// `:before` to contain the top-margins of child elements.
//
// Source: http://nicolasgallagher.com/micro-clearfix-hack/
.clearfix() {
&:before,
&:after {
content: " "; // 1
display: table; // 2
}
&:after {
clear: both;
}
}

View File

@ -0,0 +1,83 @@
// Form validation states
//
// Used in forms.less to generate the form validation CSS for warnings, errors,
// and successes.
.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {
// Color the label and help text
.help-block,
.control-label,
.radio,
.checkbox,
.radio-inline,
.checkbox-inline,
&.radio label,
&.checkbox label,
&.radio-inline label,
&.checkbox-inline label {
color: @text-color;
}
// Set the border and box shadow on specific inputs to match
.form-control {
border-color: @border-color;
.box-shadow(inset 0 1px 1px rgba(0, 0, 0, .075)); // Redeclare so transitions work
&:focus {
border-color: darken(@border-color, 10%);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 3px rgba(@brand-primary, .5);
}
}
// Set validation states also for addons
.input-group-addon {
color: @text-color;
border-color: @border-color;
background-color: @background-color;
}
// Optional feedback icon
.form-control-feedback {
color: @text-color;
}
}
// Form control focus state
//
// Generate a customized focus state and for any input with the specified color,
// which defaults to the `@input-border-focus` variable.
//
// We highly encourage you to not customize the default value, but instead use
// this to tweak colors on an as-needed basis. This aesthetic change is based on
// WebKit's default styles, but applicable to a wider range of browsers. Its
// usability and accessibility should be taken into account with any change.
//
// Example usage: change the default blue border and shadow to white for better
// contrast against a dark gray background.
.form-control-focus(@color: @input-border-focus) {
@color-rgba: rgba(red(@color), green(@color), blue(@color), .6);
&:focus {
border-color: @color;
outline: 0;
.box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}");
}
}
// Form control sizing
//
// Relative text size, padding, and border-radii changes for form controls. For
// horizontal sizing, wrap controls in the predefined grid classes. `<select>`
// element gets special love because it's special, and that's a fact!
.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {
height: @input-height;
padding: @padding-vertical @padding-horizontal;
font-size: @font-size;
line-height: @line-height;
border-radius: @border-radius;
select& {
height: @input-height;
line-height: @input-height;
}
textarea&,
select[multiple] & {
height: auto;
}
}

View File

@ -0,0 +1,59 @@
// Gradients
#gradient {
// Horizontal gradient, from left to right
//
// Creates two color stops, start and end, by specifying a color and position for each color stop.
// Color stops are not available in IE9 and below.
.horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {
background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+
background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12
background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
background-repeat: repeat-x;
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)", argb(@start-color), argb(@end-color))); // IE9 and down
}
// Vertical gradient, from top to bottom
//
// Creates two color stops, start and end, by specifying a color and position for each color stop.
// Color stops are not available in IE9 and below.
.vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {
background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+
background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12
background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
background-repeat: repeat-x;
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)", argb(@start-color), argb(@end-color))); // IE9 and down
}
.directional(@start-color: #555; @end-color: #333; @deg: 45deg) {
background-repeat: repeat-x;
background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+
background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12
background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
}
.horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {
background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);
background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);
background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);
background-repeat: no-repeat;
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)", argb(@start-color), argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback
}
.vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {
background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);
background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);
background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);
background-repeat: no-repeat;
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)", argb(@start-color), argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback
}
.radial(@inner-color: #555; @outer-color: #333) {
background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);
background-image: radial-gradient(circle, @inner-color, @outer-color);
background-repeat: no-repeat;
}
.striped(@color: rgba(255,255,255,.15); @angle: 45deg) {
background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);
background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);
background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);
}
}

View File

@ -0,0 +1,96 @@
// Framework grid generation
//
// Used only by Bootstrap to generate the correct number of grid classes given
// any value of `@grid-columns`.
.make-grid-columns() {
// Common styles for all sizes of grid columns, widths 1-12
.col(@index) { // initial
@item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
.col((@index + 1), @item);
}
.col(@index, @list) when (@index =< @grid-columns) { // general; "=<" isn't a typo
@item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
.col((@index + 1), ~"@{list}, @{item}");
}
.col(@index, @list) when (@index > @grid-columns) { // terminal
@{list} {
position: relative;
// Prevent columns from collapsing when empty
min-height: 1px;
// Inner gutter via padding
padding-left: (@grid-gutter-width / 2);
padding-right: (@grid-gutter-width / 2);
}
}
.col(1); // kickstart it
}
.float-grid-columns(@class) {
.col(@index) { // initial
@item: ~".col-@{class}-@{index}";
.col((@index + 1), @item);
}
.col(@index, @list) when (@index =< @grid-columns) { // general
@item: ~".col-@{class}-@{index}";
.col((@index + 1), ~"@{list}, @{item}");
}
.col(@index, @list) when (@index > @grid-columns) { // terminal
@{list} {
float: left;
}
}
.col(1); // kickstart it
}
.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {
.col-@{class}-@{index} {
width: percentage((@index / @grid-columns));
}
}
.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {
.col-@{class}-push-@{index} {
left: percentage((@index / @grid-columns));
}
}
.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {
.col-@{class}-push-0 {
left: auto;
}
}
.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {
.col-@{class}-pull-@{index} {
right: percentage((@index / @grid-columns));
}
}
.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {
.col-@{class}-pull-0 {
right: auto;
}
}
.calc-grid-column(@index, @class, @type) when (@type = offset) {
.col-@{class}-offset-@{index} {
margin-left: percentage((@index / @grid-columns));
}
}
// Basic looping in LESS
.loop-grid-columns(@index, @class, @type) when (@index >= 0) {
.calc-grid-column(@index, @class, @type);
// next iteration
.loop-grid-columns((@index - 1), @class, @type);
}
// Create grid for specific class
.make-grid(@class) {
.float-grid-columns(@class);
.loop-grid-columns(@grid-columns, @class, width);
.loop-grid-columns(@grid-columns, @class, pull);
.loop-grid-columns(@grid-columns, @class, push);
.loop-grid-columns(@grid-columns, @class, offset);
}

View File

@ -0,0 +1,134 @@
// Grid system
//
// Generate semantic grid columns with these mixins.
// Centered container element
.container-fixed(@gutter: @grid-gutter-width) {
margin-right: auto;
margin-left: auto;
padding-left: (@gutter / 2);
padding-right: (@gutter / 2);
&:extend(.clearfix all);
}
// Creates a wrapper for a series of columns
.make-row(@gutter: @grid-gutter-width) {
margin-left: (@gutter / -2);
margin-right: (@gutter / -2);
&:extend(.clearfix all);
}
// Generate the extra small columns
.make-xs-column(@columns; @gutter: @grid-gutter-width) {
position: relative;
float: left;
width: percentage((@columns / @grid-columns));
min-height: 1px;
padding-left: (@gutter / 2);
padding-right: (@gutter / 2);
}
.make-xs-column-offset(@columns) {
margin-left: percentage((@columns / @grid-columns));
}
.make-xs-column-push(@columns) {
left: percentage((@columns / @grid-columns));
}
.make-xs-column-pull(@columns) {
right: percentage((@columns / @grid-columns));
}
// Generate the small columns
.make-sm-column(@columns; @gutter: @grid-gutter-width) {
position: relative;
min-height: 1px;
padding-left: (@gutter / 2);
padding-right: (@gutter / 2);
@media (min-width: @screen-sm-min) {
float: left;
width: percentage((@columns / @grid-columns));
}
}
.make-sm-column-offset(@columns) {
@media (min-width: @screen-sm-min) {
margin-left: percentage((@columns / @grid-columns));
}
}
.make-sm-column-push(@columns) {
@media (min-width: @screen-sm-min) {
left: percentage((@columns / @grid-columns));
}
}
.make-sm-column-pull(@columns) {
@media (min-width: @screen-sm-min) {
right: percentage((@columns / @grid-columns));
}
}
// Generate the medium columns
.make-md-column(@columns; @gutter: @grid-gutter-width) {
position: relative;
min-height: 1px;
padding-left: (@gutter / 2);
padding-right: (@gutter / 2);
@media (min-width: @screen-md-min) {
float: left;
width: percentage((@columns / @grid-columns));
}
}
.make-md-column-offset(@columns) {
@media (min-width: @screen-md-min) {
margin-left: percentage((@columns / @grid-columns));
}
}
.make-md-column-push(@columns) {
@media (min-width: @screen-md-min) {
left: percentage((@columns / @grid-columns));
}
}
.make-md-column-pull(@columns) {
@media (min-width: @screen-md-min) {
right: percentage((@columns / @grid-columns));
}
}
// Generate the large columns
.make-lg-column(@columns; @gutter: @grid-gutter-width) {
position: relative;
min-height: 1px;
padding-left: (@gutter / 2);
padding-right: (@gutter / 2);
@media (min-width: @screen-lg-min) {
float: left;
width: percentage((@columns / @grid-columns));
}
}
.make-lg-column-offset(@columns) {
@media (min-width: @screen-lg-min) {
margin-left: percentage((@columns / @grid-columns));
}
}
.make-lg-column-push(@columns) {
@media (min-width: @screen-lg-min) {
left: percentage((@columns / @grid-columns));
}
}
.make-lg-column-pull(@columns) {
@media (min-width: @screen-lg-min) {
right: percentage((@columns / @grid-columns));
}
}

View File

@ -0,0 +1,21 @@
// CSS image replacement
//
// Heads up! v3 launched with only `.hide-text()`, but per our pattern for
// mixins being reused as classes with the same name, this doesn't hold up. As
// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`.
//
// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757
// Deprecated as of v3.0.1 (will be removed in v4)
.hide-text() {
font: ~"0/0" a;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}
// New mixin to use as of v3.0.1
.text-hide() {
.hide-text();
}

View File

@ -0,0 +1,25 @@
// Image Mixins
// - Responsive image
// - Retina image
// Responsive image
//
// Keep images from scaling beyond the width of their parents.
.img-responsive(@display: block) {
display: @display;
max-width: 100%; // Part 1: Set a maximum relative to the parent
height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching
}
// Retina image
//
// Short retina mixin for setting background-image and -size. Note that the
// spelling of `min--moz-device-pixel-ratio` is intentional.
.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {
background-image: url("@{file-1x}");
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and ( min--moz-device-pixel-ratio: 2), only screen and ( -o-min-device-pixel-ratio: 2/1), only screen and ( min-device-pixel-ratio: 2), only screen and ( min-resolution: 192dpi), only screen and ( min-resolution: 2dppx) {
background-image: url("@{file-2x}");
background-size: @width-1x @height-1x;
}
}

View File

@ -0,0 +1,12 @@
// Labels
.label-variant(@color) {
background-color: @color;
&[href] {
&:hover,
&:focus {
background-color: darken(@color, 10%);
}
}
}

View File

@ -0,0 +1,30 @@
// List Groups
.list-group-item-variant(@state; @background; @color) {
.list-group-item-@{state} {
color: @color;
background-color: @background;
a&,
button& {
color: @color;
.list-group-item-heading {
color: inherit;
}
&:hover,
&:focus {
color: @color;
background-color: darken(@background, 5%);
}
&.active,
&.active:hover,
&.active:focus {
color: #fff;
background-color: @color;
border-color: @color;
}
}
}
}

View File

@ -0,0 +1,10 @@
// Horizontal dividers
//
// Dividers (basically an hr) within dropdowns and nav lists
.nav-divider(@color: #e5e5e5) {
height: 1px;
margin: 2px 0;
overflow: hidden;
background-color: @color;
}

View File

@ -0,0 +1,9 @@
// Navbar vertical align
//
// Vertically center elements in the navbar.
// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.
.navbar-vertical-align(@element-height) {
margin-top: ((@navbar-height - @element-height) / 2);
margin-bottom: ((@navbar-height - @element-height) / 2);
}

View File

@ -0,0 +1,8 @@
// Opacity
.opacity(@opacity) {
opacity: @opacity;
// IE8 filter
@opacity-ie: (@opacity * 100);
filter: ~"alpha(opacity=@{opacity-ie})";
}

View File

@ -0,0 +1,24 @@
// Pagination
.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {
> li {
> a,
> span {
padding: @padding-vertical @padding-horizontal;
font-size: @font-size;
line-height: @line-height;
}
&:first-child {
> a,
> span {
.border-left-radius(@border-radius);
}
}
&:last-child {
> a,
> span {
.border-right-radius(@border-radius);
}
}
}
}

View File

@ -0,0 +1,24 @@
// Panels
.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {
border-color: @border;
& > .panel-heading {
color: @heading-text-color;
background-color: @heading-bg-color;
border-color: @heading-border;
+ .panel-collapse > .panel-body {
border-top-color: @border;
}
.badge {
color: @heading-bg-color;
background-color: @heading-text-color;
}
}
& > .panel-footer {
+ .panel-collapse > .panel-body {
border-bottom-color: @border;
}
}
}

View File

@ -0,0 +1,10 @@
// Progress bars
.progress-bar-variant(@color) {
background-color: @color;
// Deprecated parent class requirement as of v3.2.0
.progress-striped & {
#gradient > .striped();
}
}

View File

@ -0,0 +1,8 @@
// Reset filters for IE
//
// When you need to remove a gradient background, do not forget to use this to reset
// the IE filter for IE9 and below.
.reset-filter() {
filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)"));
}

View File

@ -0,0 +1,18 @@
.reset-text() {
font-family: @font-family-base;
// We deliberately do NOT reset font-size.
font-style: normal;
font-weight: normal;
letter-spacing: normal;
line-break: auto;
line-height: @line-height-base;
text-align: left; // Fallback for where `start` is not supported
text-align: start;
text-decoration: none;
text-shadow: none;
text-transform: none;
white-space: normal;
word-break: normal;
word-spacing: normal;
word-wrap: normal;
}

View File

@ -0,0 +1,6 @@
// Resize anything
.resizable(@direction) {
resize: @direction; // Options: horizontal, vertical, both
overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible`
}

View File

@ -0,0 +1,21 @@
// Responsive utilities
//
// More easily include all the states for responsive-utilities.less.
.responsive-visibility() {
display: block !important;
table& {
display: table !important;
}
tr& {
display: table-row !important;
}
th&,
td& {
display: table-cell !important;
}
}
.responsive-invisibility() {
display: none !important;
}

View File

@ -0,0 +1,10 @@
// Sizing shortcuts
.size(@width; @height) {
width: @width;
height: @height;
}
.square(@size) {
.size(@size; @size);
}

View File

@ -0,0 +1,6 @@
// WebKit-style focus
.tab-focus() {
outline: thin dotted;
outline-offset: 3px;
}

View File

@ -0,0 +1,28 @@
// Tables
.table-row-variant(@state; @background) {
// Exact selectors below required to override `.table-striped` and prevent
// inheritance to nested tables.
.table > thead > tr,
.table > tbody > tr,
.table > tfoot > tr {
> td.@{state},
> th.@{state},
&.@{state} > td,
&.@{state} > th {
background-color: @background;
}
}
// Hover states for `.table-hover`
// Note: this is not available for cells or rows within `thead` or `tfoot`.
.table-hover > tbody > tr {
> td.@{state}:hover,
> th.@{state}:hover,
&.@{state}:hover > td,
&:hover > .@{state},
&.@{state}:hover > th {
background-color: darken(@background, 5%);
}
}
}

View File

@ -0,0 +1,9 @@
// Typography
.text-emphasis-variant(@color) {
color: @color;
a&:hover,
a&:focus {
color: darken(@color, 5%);
}
}

View File

@ -0,0 +1,8 @@
// Text overflow
// Requires inline-block or block for proper styling
.text-overflow() {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

View File

@ -0,0 +1,254 @@
// Vendor Prefixes
//
// All vendor mixins are deprecated as of v3.2.0 due to the introduction of
// Autoprefixer in our Gruntfile. They will be removed in v4.
// - Animations
// - Backface visibility
// - Box shadow
// - Box sizing
// - Content columns
// - Hyphens
// - Placeholder text
// - Transformations
// - Transitions
// - User Select
// Animations
.animation(@animation) {
-webkit-animation: @animation;
-o-animation: @animation;
animation: @animation;
}
.animation-name(@name) {
-webkit-animation-name: @name;
animation-name: @name;
}
.animation-duration(@duration) {
-webkit-animation-duration: @duration;
animation-duration: @duration;
}
.animation-timing-function(@timing-function) {
-webkit-animation-timing-function: @timing-function;
animation-timing-function: @timing-function;
}
.animation-delay(@delay) {
-webkit-animation-delay: @delay;
animation-delay: @delay;
}
.animation-iteration-count(@iteration-count) {
-webkit-animation-iteration-count: @iteration-count;
animation-iteration-count: @iteration-count;
}
.animation-direction(@direction) {
-webkit-animation-direction: @direction;
animation-direction: @direction;
}
.animation-fill-mode(@fill-mode) {
-webkit-animation-fill-mode: @fill-mode;
animation-fill-mode: @fill-mode;
}
// Backface visibility
// Prevent browsers from flickering when using CSS 3D transforms.
// Default value is `visible`, but can be changed to `hidden`
.backface-visibility(@visibility) {
-webkit-backface-visibility: @visibility;
-moz-backface-visibility: @visibility;
backface-visibility: @visibility;
}
// Drop shadows
//
// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's
// supported browsers that have box shadow capabilities now support it.
.box-shadow(@shadow) {
-webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1
box-shadow: @shadow;
}
// Box sizing
.box-sizing(@boxmodel) {
-webkit-box-sizing: @boxmodel;
-moz-box-sizing: @boxmodel;
box-sizing: @boxmodel;
}
// CSS3 Content Columns
.content-columns(@column-count; @column-gap: @grid-gutter-width) {
-webkit-column-count: @column-count;
-moz-column-count: @column-count;
column-count: @column-count;
-webkit-column-gap: @column-gap;
-moz-column-gap: @column-gap;
column-gap: @column-gap;
}
// Optional hyphenation
.hyphens(@mode: auto) {
word-wrap: break-word;
-webkit-hyphens: @mode;
-moz-hyphens: @mode;
-ms-hyphens: @mode; // IE10+
-o-hyphens: @mode;
hyphens: @mode;
}
// Placeholder text
.placeholder(@color: @input-color-placeholder) {
// Firefox
&::-moz-placeholder {
color: @color;
opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526
}
&:-ms-input-placeholder {
color: @color;
}
// Internet Explorer 10+
&::-webkit-input-placeholder {
color: @color;
}
// Safari and Chrome
}
// Transformations
.scale(@ratio) {
-webkit-transform: scale(@ratio);
-ms-transform: scale(@ratio); // IE9 only
-o-transform: scale(@ratio);
transform: scale(@ratio);
}
.scale(@ratioX; @ratioY) {
-webkit-transform: scale(@ratioX, @ratioY);
-ms-transform: scale(@ratioX, @ratioY); // IE9 only
-o-transform: scale(@ratioX, @ratioY);
transform: scale(@ratioX, @ratioY);
}
.scaleX(@ratio) {
-webkit-transform: scaleX(@ratio);
-ms-transform: scaleX(@ratio); // IE9 only
-o-transform: scaleX(@ratio);
transform: scaleX(@ratio);
}
.scaleY(@ratio) {
-webkit-transform: scaleY(@ratio);
-ms-transform: scaleY(@ratio); // IE9 only
-o-transform: scaleY(@ratio);
transform: scaleY(@ratio);
}
.skew(@x; @y) {
-webkit-transform: skewX(@x) skewY(@y);
-ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+
-o-transform: skewX(@x) skewY(@y);
transform: skewX(@x) skewY(@y);
}
.translate(@x; @y) {
-webkit-transform: translate(@x, @y);
-ms-transform: translate(@x, @y); // IE9 only
-o-transform: translate(@x, @y);
transform: translate(@x, @y);
}
.translate3d(@x; @y; @z) {
-webkit-transform: translate3d(@x, @y, @z);
transform: translate3d(@x, @y, @z);
}
.rotate(@degrees) {
-webkit-transform: rotate(@degrees);
-ms-transform: rotate(@degrees); // IE9 only
-o-transform: rotate(@degrees);
transform: rotate(@degrees);
}
.rotateX(@degrees) {
-webkit-transform: rotateX(@degrees);
-ms-transform: rotateX(@degrees); // IE9 only
-o-transform: rotateX(@degrees);
transform: rotateX(@degrees);
}
.rotateY(@degrees) {
-webkit-transform: rotateY(@degrees);
-ms-transform: rotateY(@degrees); // IE9 only
-o-transform: rotateY(@degrees);
transform: rotateY(@degrees);
}
.perspective(@perspective) {
-webkit-perspective: @perspective;
-moz-perspective: @perspective;
perspective: @perspective;
}
.perspective-origin(@perspective) {
-webkit-perspective-origin: @perspective;
-moz-perspective-origin: @perspective;
perspective-origin: @perspective;
}
.transform-origin(@origin) {
-webkit-transform-origin: @origin;
-moz-transform-origin: @origin;
-ms-transform-origin: @origin; // IE9 only
transform-origin: @origin;
}
// Transitions
.transition(@transition) {
-webkit-transition: @transition;
-o-transition: @transition;
transition: @transition;
}
.transition-property(@transition-property) {
-webkit-transition-property: @transition-property;
transition-property: @transition-property;
}
.transition-delay(@transition-delay) {
-webkit-transition-delay: @transition-delay;
transition-delay: @transition-delay;
}
.transition-duration(@transition-duration) {
-webkit-transition-duration: @transition-duration;
transition-duration: @transition-duration;
}
.transition-timing-function(@timing-function) {
-webkit-transition-timing-function: @timing-function;
transition-timing-function: @timing-function;
}
.transition-transform(@transition) {
-webkit-transition: -webkit-transform @transition;
-moz-transition: -moz-transform @transition;
-o-transition: -o-transform @transition;
transition: transform @transition;
}
// User select
// For selecting text on the page
.user-select(@select) {
-webkit-user-select: @select;
-moz-user-select: @select;
-ms-user-select: @select; // IE10+
user-select: @select;
}

View File

@ -0,0 +1,373 @@
img {
max-width: 100%;
height: auto;
}
textarea {
resize: vertical;
}
// anouncement bars
.announcement {
padding: 3px 10px;
text-align: center;
font-weight: 300;
color: white;
display: block;
background-color: @brand-primary;
a {
text-decoration: underline;
color: white;
transition: 250ms all ease;
}
&:hover,
&:focus {
transition: 250ms all ease;
color: darken(white, 5%);
text-decoration: none;
background-color: darken(@brand-primary, 5%);
}
strong {
font-weight: 400;
}
}
.annoucement-warning {
background-color: @brand-danger;
&:hover,
&:focus {
background-color: darken(@brand-danger, 5%);
a,
a:hover {
text-decoration: none;
}
}
}
.annoucement-danger {
background-color: @brand-danger;
a:hover,
a:focus {
color: darken(white, 5%);
a,
a:hover {
text-decoration: none;
}
}
}
// address icenticons
.address-identicon-container {
padding-left: 0;
padding-top: @space-md;
text-align: left;
@media screen and (max-width: @grid-float-breakpoint) {
padding-left: @space-lg;
padding-right: @space-lg;
padding-top: 0;
}
}
.address-identicon-container-right {
padding-right: 0;
padding-top: @space-md;
text-align: right;
.addressIdenticon {
float: right;
}
@media screen and (max-width: @grid-float-breakpoint) {
padding-left: @space-lg;
padding-right: @space-lg;
padding-top: 0;
}
}
.address-identicon-container-offline {
padding: 0;
margin-left: -15px;
}
.addressIdenticon {
width: 4rem;
height: 4rem;
background-size: cover;
background-repeat: no-repeat;
border-radius: 50%;
box-shadow: inset rgba(255, 255, 255, 0.5) 0 2px 2px,
inset rgba(0, 0, 0, 0.6) 0 -1px 8px;
}
.addressIdenticon.med {
width: 3rem;
height: 3rem;
}
.addressIdenticon.small {
width: 2rem;
height: 2rem;
}
.addressIdenticon.inline {
display: inline-block;
}
.addressIdenticon.float {
float: left;
margin-right: @space-sm;
}
// helpers
.wrap {
word-wrap: break-word;
}
.bigger-on-mobile.form-control[readonly] {
height: 60px;
@media screen and (max-width: 767px) {
height: 100px;
}
}
// help page
#paneHelp {
h3 {
margin-top: 2em;
}
}
// monospace things
.mono,
.form-control,
#accountAddress,
#accountBalance,
#accountBalanceUsd,
#accountBalanceEur,
#accountBalanceBtc,
#accountBalancePopMB-0,
#accountBalancePopMB-2,
#accountAddressMainTbl-1 {
font-family: @font-family-monospace;
font-weight: normal;
letter-spacing: .02em;
}
// QR Code on Offline Transactions Page
.offline-qrcode {
margin-top: -150px;
max-width: 300px;
@media screen and (max-width: 942px) {
margin-top: -78px;
}
@media screen and (max-width: 769px) {
margin-top: 0;
}
}
// collapsable containers
.collapse-container {
h2,
h4 {
cursor: pointer;
}
.collapse-button {
float: left;
font-weight: 500;
user-select: none;
padding: 10px;
margin: -10px -35px;
font-size: 24px;
line-height: 1.6;
}
}
// help collapsable containers
.help .collapse-container {
margin: 40px 0;
.collapse-button {
margin: -10px -30px;
font-size: 20px;
line-height: 1;
}
}
// little x image next to custom tokens
.token-remove {
width: @font-size-small;
height: @font-size-small;
position: absolute;
left: 18px;
cursor: pointer;
}
.node-remove {
width: 16px;
height: 16px;
position: absolute;
right: 6px;
top: 8px;
}
.m-addresses td:first-child {
max-width: 50px;
min-width: 50px;
}
.m-addresses td:last-child {
text-align: right;
}
h2 a.isActive {
color: #333;
cursor: default;
&:hover,
&:active {
color: #333;
cursor: default;
}
}
.item {
margin: 6px 0;
}
.output.well {
padding: @space-sm @space;
margin-top: -@space/2;
p {
margin: @space-sm 0;
}
}
label small {
color: @gray-light;
}
.write-address {
.col-xs-1 {
padding: 0;
}
.col-xs-11 {
padding-right: 10px;
}
}
.write-boolean label {
display: block;
}
.decrypt-drtv {
padding: @space 0;
label.radio {
padding: 0 @space-lg;
}
}
.qr-code {
max-width: 17rem;
margin: auto;
}
.qr-pkey-container {
position: relative;
}
.qr-overlay {
background-color: black;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.contracts {
h4 + .dropdown,
h4 + .dropdown .btn {
margin-top: 0;
}
a.isActive {
color: @text-color;
}
.dropdown-toggle {
display: block;
text-align: left;
white-space: normal;
.caret {
position: absolute;
right: @space;
top: 1.25rem;
}
}
.dropdown-menu-left {
font-size: @font-size-small;
left: auto;
right: 0;
min-width: 37rem;
small {
float: right;
}
}
}
.view-wallet-content {
@media screen and (min-width: @grid-float-breakpoint) {
padding-left: @space*3;
}
h5 {
margin-bottom: @space-xs;
}
a.isActive {
color: @text-color;
}
}
#selectedTypeLedger ol {
padding-left: 1rem;
}
.loading-wrap {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: fadeOut(black, 30%);
z-index: 999;
text-align: center;
.loading {
position: absolute;
text-align: center;
top: 40%;
left: 50%;
transform: translate(-50%, -60%);
}
img {
border-radius: 50%;
}
h1 {
animation: opacity 2000ms infinite ease-in-out;
color: white;
}
@keyframes opacity {
from,
to {
opacity: 0;
}
50% {
opacity: 1;
}
}
}
.embedded-logo {
height: auto;
width: 100%;
max-width: 290px;
padding: .5rem 0;
}
.ens-response {
color: @gray;
}

View File

@ -0,0 +1,28 @@
#etherWalletPopUp {
padding: 10px;
position: relative;
min-width: 346px;
.back-icon {
position: absolute;
left: 5px;
top: 5px;
&:hover,
&:active {
outline: 0;
}
}
}
.quicksend-address {
font-family: @font-family-monospace;
max-width: 170px;
word-wrap: break-word;
font-size: 12px;
font-weight: 300;
display: block;
}
.chrome-tokens span {
display: inline-block;
}

View File

@ -0,0 +1,7 @@
@import 'etherwallet-variables.less';
// Core variables and mixins
@import 'bootstrap/mixins.less';
// Utility classes
@import 'etherwallet-custom.less';
@import 'etherwallet-ext-custom.less';
@import 'etherwallet-utilities.less';

View File

@ -0,0 +1,92 @@
/* Custom Utilities */
.text-navy {
color: @ether-navy;
}
.text-gray-lighter {
color: @gray-lighter;
}
.text-blue {
color: @ether-blue;
}
.text-white {
color: #fff;
}
.bg-navy {
background: @ether-navy;
}
.bg-gray-lighter {
background-color: @gray-lighter;
}
.bg-blue {
background-color: @ether-blue;
}
.bg-white {
background-color: #fff;
}
.text-serif {
font-family: @font-family-serif;
}
.text-sans-serif {
font-family: @font-family-sans-serif;
}
.pad-v-sm {
padding-top: .5em;
padding-bottom: .5em;
}
.pad-v-md {
padding-top: 1em;
padding-bottom: 1em;
}
.pad-v-lg {
padding-top: 1.5em;
padding-bottom: 1.5em;
}
.pad-v-xl {
padding-top: 2em;
padding-bottom: 2em;
}
.marg-v-sm {
margin-top: .5em;
margin-bottom: .5em;
}
.marg-v-md {
margin-top: 1em;
margin-bottom: 1em;
}
.marg-v-lg {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
.marg-v-xl {
margin-top: 2em;
margin-bottom: 2em;
}
.img-fill {
width: 100%;
height: auto;
max-width: 100%;
}
.no-scroll {
height: 100%;
overflow: hidden;
}

View File

@ -0,0 +1,362 @@
// Colors
@ether-navy: #163151;
@ether-blue: #0e97c0;
@space-xs: 0.25rem;
@space-sm: 0.5rem;
@space-md: 0.75rem;
@space: 1rem;
@space-lg: 1.5rem;
@space-xl: 2rem;
@gray-base: #000;
@gray-darker: lighten(@gray-base, 13.5%);
@gray-dark: lighten(@gray-base, 20%);
@gray: #737373;
@gray-light: #9a9a9a;
@gray-lighter: #ececec;
@gray-lightest: #fafafa;
@brand-primary: @ether-blue;
@brand-success: #5dba5a;
@brand-info: @ether-navy;
@brand-warning: #ff9800;
@brand-danger: #ea4b40;
@body-bg: #fff;
@text-color: @gray-dark;
@link-color: @brand-primary;
@link-hover-color: darken(@link-color, 5%);
@link-hover-decoration: none;
@transition: 500ms all ease-in-out;
// Typography
@font-family-sans-serif: 'Lato', sans-serif;
@font-family-serif: Georgia, 'Times New Roman', Times, serif;
@font-family-monospace: 'Roboto Mono', Menlo, Monaco, Consolas, 'Courier New', monospace;
@font-family-base: @font-family-sans-serif;
@base: 15;
@font-size-pixels: @base+px;
@font-size-pixels-xl: @base+1px; // for xl screens
@font-size-pixels-sm: @base+px; // for small screens
@font-size-large-bump: 2.25rem; // 33.75
@font-size-large: 1.9rem; // 28.5
@font-size-medium-bump: 1.5rem; // 22.5
@font-size-medium: 1.3rem; // 19.5
@font-size-bump-more: 1.15rem; // 17.25
@font-size-bump: 1.07rem; // 16.05
@font-size-base: 1rem; // 15
@font-size-small: 0.92rem; // 13.8
@font-size-xs: 0.8rem; // 12
@font-size-h1: @font-size-large-bump;
@font-size-h2: @font-size-large;
@font-size-h3: @font-size-medium-bump;
@font-size-h4: @font-size-medium;
@font-size-h5: @font-size-bump-more;
@font-size-h6: @font-size-bump;
@line-height-base: 1.4;
@line-height-computed: 1.4;
@headings-font-family: inherit;
@headings-font-weight: 700;
@headings-line-height: 1.2;
@headings-color: inherit;
// Spacing
@padding-base-vertical: @space*.6;
@padding-base-horizontal: @space;
@padding-large-vertical: @space-md;
@padding-large-horizontal: @space-xl;
@padding-small-vertical: 0.1rem;
@padding-small-horizontal: @space-sm;
@padding-xs-vertical: @space-xs;
@padding-xs-horizontal: 0.2rem;
@line-height-large: 1.2;
@line-height-small: 1.5;
@border-radius: 2px;
@component-active-color: #fff;
@component-active-bg: @brand-primary;
@caret-width-base: @space-xs;
@caret-width-large: @space-xs;
// Tables
@table-cell-padding: @space-sm;
@table-condensed-cell-padding: @space-xs;
@table-bg: transparent;
@table-bg-accent: #f9f9f9;
@table-bg-hover: @gray-lightest;
@table-bg-active: @table-bg-hover;
@table-border-color: #ddd;
// Buttons
@btn-font-weight: normal;
@btn-default-color: #333;
@btn-default-bg: #ececec;
@btn-default-border: @gray-lighter;
@btn-primary-color: #fff;
@btn-primary-bg: @brand-primary;
@btn-primary-border: darken(@btn-primary-bg, 5%);
@btn-success-color: #fff;
@btn-success-bg: @brand-success;
@btn-success-border: darken(@btn-success-bg, 5%);
@btn-info-color: #fff;
@btn-info-bg: @brand-info;
@btn-info-border: darken(@btn-info-bg, 5%);
@btn-warning-color: #fff;
@btn-warning-bg: @brand-warning;
@btn-warning-border: darken(@btn-warning-bg, 5%);
@btn-danger-color: #fff;
@btn-danger-bg: @brand-danger;
@btn-danger-border: darken(@btn-danger-bg, 5%);
@btn-link-disabled-color: @gray-light;
// Forms
@input-bg: #fff;
@input-bg-disabled: @gray-lightest;
@input-color: @gray;
@input-border: @gray-lighter;
@input-border-focus: @brand-primary;
@input-color-placeholder: darken(@gray-lighter, 10%);
@input-height-base: 2.55rem;
@input-height-large: 4rem;
@input-height-small: 2rem;
@form-group-margin-bottom: @space-sm;
@legend-color: @gray-dark;
@legend-border-color: #e5e5e5;
@input-group-addon-bg: @gray-lighter;
@input-group-addon-border-color: @input-border;
@cursor-disabled: default;
@dropdown-bg: #fff;
@dropdown-border: rgba(0, 0, 0, 0.15);
@dropdown-fallback-border: @gray-lighter;
@dropdown-divider-bg: #e5e5e5;
@dropdown-link-color: @ether-navy;
@dropdown-link-hover-color: @ether-blue;
@dropdown-link-hover-bg: @gray-lightest;
@dropdown-link-active-color: @component-active-color;
@dropdown-link-active-bg: @component-active-bg;
@dropdown-link-disabled-color: @gray-light;
@dropdown-header-color: @gray-light;
@dropdown-caret-color: #000;
@zindex-navbar: 1000;
@zindex-dropdown: 1000;
@zindex-popover: 1060;
@zindex-tooltip: 1070;
@zindex-navbar-fixed: 1030;
@zindex-modal-background: 1040;
@zindex-modal: 1050;
@zindex-alerts: 1060;
@screen-xs: 32rem;
@screen-xs-min: @screen-xs;
@screen-sm: 51.2rem;
@screen-sm-min: @screen-sm;
@screen-md: 66.133333333rem;
@screen-md-min: @screen-md;
@screen-lg: 80rem;
@screen-lg-min: @screen-lg;
@screen-xl: 94rem;
@screen-xl-min: @screen-xl;
@screen-xs-max: (@screen-sm-min - 1);
@screen-sm-max: (@screen-md-min - 1);
@screen-md-max: (@screen-lg-min - 1);
@screen-lg-max: (@screen-xl-min - 1);
@grid-columns: 12;
@grid-gutter-width: 3rem;
@grid-float-breakpoint: @screen-sm-min;
@grid-float-breakpoint-max: (@grid-float-breakpoint - 1);
@cont-padding: 5%;
@cont-padding-lg: 7.5%;
@container-tablet: (@screen-sm + @grid-gutter-width);
@container-sm: @container-tablet;
@container-desktop: (@screen-md + @grid-gutter-width);
@container-md: @container-desktop;
@container-large-desktop: (@screen-lg + @grid-gutter-width);
@container-lg: @container-large-desktop;
@state-success-text: darken(@brand-success, 10%);
@state-success-bg: #dff0d8;
@state-success-border: darken(spin(@state-success-bg, -10), 5%);
@state-info-text: darken(@brand-info, 10%);
@state-info-bg: #d9edf7;
@state-info-border: darken(spin(@state-info-bg, -10), 7%);
@state-warning-text: darken(@brand-warning, 10%);
@state-warning-bg: #fcf8e3;
@state-warning-border: darken(spin(@state-warning-bg, -10), 5%);
@state-danger-text: darken(@brand-danger, 10%);
@state-danger-bg: #f2dede;
@state-danger-border: darken(spin(@state-danger-bg, -10), 5%);
@tooltip-max-width: 200px;
@tooltip-color: #fff;
@tooltip-bg: #000;
@tooltip-opacity: 0.9;
@tooltip-arrow-width: @space-sm;
@tooltip-arrow-color: @tooltip-bg;
@label-default-bg: @gray-light;
@label-primary-bg: @brand-primary;
@label-success-bg: @brand-success;
@label-info-bg: @brand-info;
@label-warning-bg: @brand-warning;
@label-danger-bg: @brand-danger;
@label-color: #fff;
@label-link-hover-color: #fff;
@modal-inner-padding: @space*1.5;
@modal-title-padding: @space;
@modal-title-line-height: @line-height-base;
@modal-content-bg: #fff;
@modal-content-border-color: rgba(0, 0, 0, 0.2);
@modal-content-fallback-border-color: #999;
@modal-backdrop-bg: #000;
@modal-backdrop-opacity: 0.5;
@modal-header-border-color: #e5e5e5;
@modal-footer-border-color: @modal-header-border-color;
@modal-lg: 70rem;
@modal-md: 50rem;
@modal-sm: 30rem;
@alert-border-radius: @border-radius;
@alert-link-font-weight: bold;
@alert-success-bg: @brand-success;
@alert-success-text: white;
@alert-success-border: @alert-success-bg;
@alert-info-bg: @brand-primary;
@alert-info-text: white;
@alert-info-border: @alert-info-bg;
@alert-warning-bg: @brand-warning;
@alert-warning-text: white;
@alert-warning-border: @alert-warning-bg;
@alert-danger-bg: @brand-danger;
@alert-danger-text: white;
@alert-danger-border: @alert-danger-bg;
@progress-bg: @gray-lightest;
@progress-bar-color: #fff;
@progress-border-radius: @border-radius;
@progress-bar-bg: @brand-primary;
@progress-bar-success-bg: @brand-success;
@progress-bar-warning-bg: @brand-warning;
@progress-bar-danger-bg: @brand-danger;
@progress-bar-info-bg: @brand-info;
@list-group-bg: #fff;
@list-group-border: #ddd;
@list-group-border-radius: @border-radius;
@list-group-hover-bg: @gray-lightest;
@list-group-active-color: @component-active-color;
@list-group-active-bg: @component-active-bg;
@list-group-active-border: @list-group-active-bg;
@list-group-active-text-color: lighten(@list-group-active-bg, 40%);
@list-group-disabled-color: @gray-light;
@list-group-disabled-bg: @gray-lighter;
@list-group-disabled-text-color: @list-group-disabled-color;
@list-group-link-color: #555;
@list-group-link-hover-color: @list-group-link-color;
@list-group-link-heading-color: #333;
@thumbnail-padding: 4px;
@thumbnail-bg: @body-bg;
@thumbnail-border: #ddd;
@thumbnail-border-radius: @border-radius;
@thumbnail-caption-color: @text-color;
@thumbnail-caption-padding: 9px;
@well-bg: @gray-lightest;
@well-border: darken(@well-bg, 7%);
@badge-font-weight: bold;
@badge-line-height: 1;
@badge-border-radius: 10px;
@close-font-weight: bold;
@close-color: #000;
@close-text-shadow: 0 1px 0 #fff;
@code-color: #c7254e;
@code-bg: #f9f2f4;
@kbd-color: #fff;
@kbd-bg: #333;
@pre-bg: @gray-lightest;
@pre-color: @gray-dark;
@pre-border-color: @gray-lighter;
@pre-scrollable-max-height: 340px;
@component-offset-horizontal: 180px;
@text-muted: @gray-light;
@abbr-border-color: @gray-light;
@headings-small-color: inherit;
@blockquote-small-color: @gray-light;
@blockquote-font-size: (@font-size-base * 1.25);
@blockquote-border-color: @gray-lighter;
@page-header-border-color: @gray-lighter;
@dl-horizontal-offset: @component-offset-horizontal;
@hr-border: @gray-lighter;

View File

@ -1,8 +1,6 @@
import React from 'react';
import { AddressFieldFactory } from './AddressFieldFactory';
import { donationAddressMap } from 'config';
import translate from 'translations';
import { Input } from 'components/ui';
interface Props {
isReadOnly?: boolean;
@ -11,20 +9,16 @@ interface Props {
export const AddressField: React.SFC<Props> = ({ isReadOnly }) => (
<AddressFieldFactory
withProps={({ currentTo, isValid, onChange, readOnly }) => (
<div className="input-group-wrapper">
<label className="input-group">
<div className="input-group-header">{translate('SEND_ADDR_SHORT')}</div>
<Input
className={`input-group-input ${isValid ? '' : 'invalid'}`}
type="text"
value={currentTo.raw}
placeholder={donationAddressMap.ETH}
readOnly={!!(isReadOnly || readOnly)}
spellCheck={false}
onChange={onChange}
/>
</label>
</div>
<React.Fragment>
<input
className={`form-control ${isValid ? 'is-valid' : 'is-invalid'}`}
type="text"
value={currentTo.raw}
placeholder={donationAddressMap.ETH}
readOnly={!!(isReadOnly || readOnly)}
onChange={onChange}
/>
</React.Fragment>
)}
/>
);

View File

@ -1,5 +1,6 @@
import React, { Component } from 'react';
import { Identicon, Spinner } from 'components/ui';
import translate from 'translations';
import { Query } from 'components/renderCbs';
import { ICurrentTo, getCurrentTo, isValidCurrentTo } from 'selectors/transaction';
import { connect } from 'react-redux';
@ -48,6 +49,7 @@ class AddressInputFactoryClass extends Component<Props> {
return (
<div className="row form-group">
<div className="col-xs-11">
<label>{translate('SEND_addr')}:</label>
<Query
params={['readOnly']}
withQuery={({ readOnly }) =>

View File

@ -1,49 +1,43 @@
@import 'common/sass/variables';
@import 'common/sass/mixins';
@import "common/sass/variables";
@import "common/sass/mixins";
.BetaAgreement {
.AlphaAgreement {
@include cover-message;
background: $brand-info;
&-content {
h2 {
text-align: center;
}
&-buttons {
padding-top: 20px;
&-btn {
display: block;
width: 100%;
max-width: 280px;
max-width: 240px;
margin: 0 auto;
border: none;
padding: 0;
transition: $transition;
outline: none;
&.is-continue {
&.is-reject {
height: 60px;
line-height: 60px;
font-size: 22px;
background: rgba(#fff, 0.96);
color: $gray-dark;
color: $gray;
border-radius: 4px;
margin-bottom: 20px;
&:hover {
background: #fff;
color: $gray-darker;
}
}
&.is-reject {
&.is-continue {
background: none;
color: #fff;
opacity: 0.7;
&:hover {
opacity: 1;
text-decoration: underline;
}
}
}
@ -57,7 +51,7 @@
background: #fff;
transition: all 500ms ease 400ms;
.BetaAgreement-content {
.AlphaAgreement-content {
opacity: 0;
transform: translateY(15px);
transition: all 500ms ease;

View File

@ -0,0 +1,66 @@
import React from 'react';
import './index.scss';
const LS_KEY = 'acknowledged-alpha';
interface State {
isFading: boolean;
hasAcknowledged: boolean;
}
export default class AlphaAgreement extends React.PureComponent<{}, State> {
public state = {
hasAcknowledged: !!localStorage.getItem(LS_KEY),
isFading: false
};
public render() {
if (this.state.hasAcknowledged) {
return null;
}
const isFading = this.state.isFading ? 'is-fading' : '';
return (
<div className={`AlphaAgreement ${isFading}`}>
<div className="AlphaAgreement-content">
<h2>This is an Unstable Version of MyCrypto</h2>
<p>
You are about to access a beta version of MyCrypto that is currently in development. In
its current state, it should only be used for testing, not for important transactions.
</p>
<p>
Any wallets you generate should not hold a significant value, and any transactions you
make should be for small amounts. MyCrypto does not claim responsibility for any issues
that happen while using the beta version.
</p>
<p>Are you sure you would like to continue?</p>
<div className="AlphaAgreement-content-buttons">
<button className="AlphaAgreement-content-buttons-btn is-reject" onClick={this.reject}>
No, take me to prod
</button>
<button
className="AlphaAgreement-content-buttons-btn is-continue"
onClick={this.doContinue}
>
Yes, continue to beta
</button>
</div>
</div>
</div>
);
}
private doContinue = () => {
localStorage.setItem(LS_KEY, 'true');
this.setState({ isFading: true });
setTimeout(() => {
this.setState({ hasAcknowledged: true });
}, 1000);
};
private reject = () => {
window.location.assign('https://mycrypto.com');
};
}

View File

@ -1,8 +1,7 @@
import React from 'react';
import { AmountFieldFactory } from './AmountFieldFactory';
import { UnitDropDown } from 'components';
import translate from 'translations';
import { Input } from 'components/ui';
import translate, { translateRaw } from 'translations';
interface Props {
hasUnitDropdown?: boolean;
@ -17,28 +16,25 @@ export const AmountField: React.SFC<Props> = ({
}) => (
<AmountFieldFactory
withProps={({ currentValue: { raw }, isValid, onChange, readOnly }) => (
<div className="input-group-wrapper">
<label className="input-group input-group-inline">
<div className="input-group-header">{translate('SEND_AMOUNT_SHORT')}</div>
<Input
className={`input-group-input ${
isAmountValid(raw, customValidator, isValid) ? '' : 'invalid'
<React.Fragment>
<label>{translate('SEND_amount')}</label>
<div className="input-group">
<input
className={`form-control ${
isAmountValid(raw, customValidator, isValid) ? 'is-valid' : 'is-invalid'
}`}
type="number"
placeholder={'1'}
placeholder={translateRaw('SEND_amount_short')}
value={raw}
readOnly={!!readOnly}
onChange={onChange}
/>
{hasUnitDropdown && <UnitDropDown showAllTokens={showAllTokens} />}
</label>
</div>
</div>
</React.Fragment>
)}
/>
);
const isAmountValid = (
raw: string,
customValidator: ((rawAmount: string) => boolean) | undefined,
isValid: boolean
) => (customValidator ? customValidator(raw) : isValid);
const isAmountValid = (raw, customValidator, isValid) =>
customValidator ? customValidator(raw) : isValid;

View File

@ -2,28 +2,6 @@
@import 'common/sass/mixins';
.AccountInfo {
&-copy {
display: inline-block;
cursor: pointer;
color: $text-color;
font-size: $font-size-xs;
opacity: 0.5;
transition: $transition;
&:hover{
opacity: 1;
}
&.is-copied{
color: $brand-success;
opacity: 1;
}
.fa {
margin-right: $space-xs;
}
}
&-section {
margin-top: $space * 1.5;
@ -85,7 +63,6 @@
}
&-addr {
margin-top: -$space-xs;
word-wrap: break-word;
@include mono;
}

View File

@ -1,16 +1,14 @@
import React from 'react';
import { connect } from 'react-redux';
import { toChecksumAddress } from 'ethereumjs-util';
import { CopyToClipboard } from 'react-copy-to-clipboard';
import { Identicon, UnitDisplay, Address, NewTabLink } from 'components/ui';
import { Identicon, UnitDisplay } from 'components/ui';
import { IWallet, Balance, TrezorWallet, LedgerWallet } from 'libs/wallet';
import React from 'react';
import translate from 'translations';
import './AccountInfo.scss';
import Spinner from 'components/ui/Spinner';
import { getNetworkConfig, getOffline } from 'selectors/config';
import { AppState } from 'reducers';
import { connect } from 'react-redux';
import { NetworkConfig } from 'types/network';
import { TSetAccountBalance, setAccountBalance } from 'actions/wallet';
import './AccountInfo.scss';
interface OwnProps {
wallet: IWallet;
@ -26,7 +24,6 @@ interface State {
showLongBalance: boolean;
address: string;
confirmAddr: boolean;
copied: boolean;
}
interface DispatchProps {
@ -39,12 +36,11 @@ class AccountInfo extends React.Component<Props, State> {
public state = {
showLongBalance: false,
address: '',
confirmAddr: false,
copied: false
confirmAddr: false
};
public setAddressFromWallet() {
const address = this.props.wallet.getAddressString();
public async setAddressFromWallet() {
const address = await this.props.wallet.getAddressString();
if (address !== this.state.address) {
this.setState({ address });
}
@ -73,17 +69,6 @@ class AccountInfo extends React.Component<Props, State> {
});
};
public onCopy = () => {
this.setState(state => {
return {
copied: !state.copied
};
});
setTimeout(() => {
this.setState({ copied: false });
}, 2000);
};
public render() {
const { network, balance, isOffline } = this.props;
const { address, showLongBalance, confirmAddr } = this.state;
@ -98,24 +83,13 @@ class AccountInfo extends React.Component<Props, State> {
const wallet = this.props.wallet as LedgerWallet | TrezorWallet;
return (
<div className="AccountInfo">
<h5 className="AccountInfo-section-header">{translate('SIDEBAR_ACCOUNTADDR')}</h5>
<h5 className="AccountInfo-section-header">{translate('sidebar_AccountAddr')}</h5>
<div className="AccountInfo-section AccountInfo-address-section">
<div className="AccountInfo-address-icon">
<Identicon address={address} size="100%" />
</div>
<div className="AccountInfo-address-wrapper">
<div className="AccountInfo-address-addr">
<Address address={address} />
</div>
<CopyToClipboard onCopy={this.onCopy} text={toChecksumAddress(address)}>
<div
className={`AccountInfo-copy ${this.state.copied ? 'is-copied' : ''}`}
title="Copy To clipboard"
>
<i className="fa fa-copy" />
<span>{this.state.copied ? 'copied!' : 'copy address'}</span>
</div>
</CopyToClipboard>
<div className="AccountInfo-address-addr">{address}</div>
</div>
</div>
@ -134,9 +108,7 @@ class AccountInfo extends React.Component<Props, State> {
});
}}
>
{confirmAddr
? null
: translate('SIDEBAR_DISPLAY_ADDR', { $wallet: wallet.getWalletType() })}
{confirmAddr ? null : 'Display address on ' + wallet.getWalletType()}
</a>
{confirmAddr ? (
<span className="AccountInfo-address-confirm">
@ -147,7 +119,7 @@ class AccountInfo extends React.Component<Props, State> {
)}
<div className="AccountInfo-section">
<h5 className="AccountInfo-section-header">{translate('SIDEBAR_ACCOUNTBAL')}</h5>
<h5 className="AccountInfo-section-header">{translate('sidebar_AccountBal')}</h5>
<ul className="AccountInfo-list">
<li className="AccountInfo-list-item AccountInfo-balance">
<span
@ -162,21 +134,17 @@ class AccountInfo extends React.Component<Props, State> {
symbol={balance.wei ? network.name : null}
/>
</span>
{balance.wei && (
<React.Fragment>
{balance.isPending ? (
<Spinner />
) : (
!isOffline && (
<button
className="AccountInfo-section-refresh"
onClick={this.props.setAccountBalance}
>
<i className="fa fa-refresh" />
</button>
)
)}
</React.Fragment>
{balance.isPending ? (
<Spinner />
) : (
!isOffline && (
<button
className="AccountInfo-section-refresh"
onClick={this.props.setAccountBalance}
>
<i className="fa fa-refresh" />
</button>
)
)}
</li>
</ul>
@ -184,20 +152,28 @@ class AccountInfo extends React.Component<Props, State> {
{(!!blockExplorer || !!tokenExplorer) && (
<div className="AccountInfo-section">
<h5 className="AccountInfo-section-header">{translate('SIDEBAR_TRANSHISTORY')}</h5>
<h5 className="AccountInfo-section-header">{translate('sidebar_TransHistory')}</h5>
<ul className="AccountInfo-list">
{!!blockExplorer && (
<li className="AccountInfo-list-item">
<NewTabLink href={blockExplorer.addressUrl(address)}>
<a
href={blockExplorer.addressUrl(address)}
target="_blank"
rel="noopener noreferrer"
>
{`${network.name} (${blockExplorer.origin})`}
</NewTabLink>
</a>
</li>
)}
{!!tokenExplorer && (
<li className="AccountInfo-list-item">
<NewTabLink href={tokenExplorer.address(address)}>
<a
href={tokenExplorer.address(address)}
target="_blank"
rel="noopener noreferrer"
>
{`Tokens (${tokenExplorer.name})`}
</NewTabLink>
</a>
</li>
)}
</ul>

View File

@ -41,6 +41,7 @@
flex-wrap: nowrap;
align-items: center;
&-fiat-symbol {
height: 18px;
width: 18px;
margin-right: 0.5rem;
text-align: center;

View File

@ -8,6 +8,7 @@ import { chain, flatMap } from 'lodash';
import { TokenBalance, getShownTokenBalances } from 'selectors/wallet';
import { Balance } from 'libs/wallet';
import './EquivalentValues.scss';
import { Wei } from 'libs/units';
import { AppState } from 'reducers';
import { getNetworkConfig, getOffline } from 'selectors/config';
import { connect } from 'react-redux';
@ -15,7 +16,6 @@ import btcIco from 'assets/images/bitcoin.png';
import ethIco from 'assets/images/ether.png';
import repIco from 'assets/images/augur.png';
import { NetworkConfig } from 'types/network';
import BN from 'bn.js';
interface AllValue {
symbol: string;
@ -51,14 +51,6 @@ interface DispatchProps {
fetchCCRates: TFetchCCRatesRequested;
}
interface FiatSymbols {
[key: string]: string;
}
interface Rates {
[rate: string]: number;
}
type Props = StateProps & DispatchProps;
class EquivalentValues extends React.Component<Props, State> {
@ -89,12 +81,11 @@ class EquivalentValues extends React.Component<Props, State> {
}
public componentWillReceiveProps(nextProps: Props) {
const { balance, tokenBalances, isOffline, network } = this.props;
const { balance, tokenBalances, isOffline } = this.props;
if (
nextProps.balance !== balance ||
nextProps.tokenBalances !== tokenBalances ||
nextProps.isOffline !== isOffline ||
nextProps.network.unit !== network.unit
nextProps.isOffline !== isOffline
) {
const defaultOption = this.defaultOption(
nextProps.balance,
@ -118,7 +109,7 @@ class EquivalentValues extends React.Component<Props, State> {
}
}
public selectOption = (equivalentValues: Option) => {
public selectOption = equivalentValues => {
this.setState({ equivalentValues });
};
@ -128,38 +119,28 @@ class EquivalentValues extends React.Component<Props, State> {
const isFetching =
!balance || balance.isPending || !tokenBalances || Object.keys(rates).length === 0;
const pairRates = this.generateValues(equivalentValues.label, equivalentValues.value);
const fiatSymbols: FiatSymbols = {
const fiatSymbols = {
USD: '$',
EUR: '€',
GBP: '£',
CHF: ' '
};
const coinAndTokenSymbols: any = {
const coinAndTokenSymbols = {
BTC: btcIco,
ETH: ethIco,
REP: repIco
};
interface ValueProps {
className: string;
rate: string;
value: BN | null;
symbol?: string;
icon?: string;
key?: number | string;
}
const Value = (props: ValueProps) => (
<div className={`EquivalentValues-values-currency ${props.className}`}>
<img src={props.icon} />
{!!props.symbol && (
<span className="EquivalentValues-values-currency-fiat-symbol">{props.symbol}</span>
)}
<span className="EquivalentValues-values-currency-label">{props.rate}</span>{' '}
const Value = ({ className = '', rate, value, symbol = '', icon = '' }) => (
<div className={`EquivalentValues-values-currency ${className}`}>
<img src={icon} />
{!!symbol && <span className="EquivalentValues-values-currency-fiat-symbol">{symbol}</span>}
<span className="EquivalentValues-values-currency-label">{rate}</span>{' '}
<span className="EquivalentValues-values-currency-value">
<UnitDisplay
unit={'ether'}
value={props.value}
displayShortBalance={rateSymbols.isFiat(props.rate) ? 2 : 3}
value={value}
displayShortBalance={rateSymbols.isFiat(rate) ? 2 : 3}
checkOffline={true}
/>
</span>
@ -169,13 +150,13 @@ class EquivalentValues extends React.Component<Props, State> {
return (
<div className="EquivalentValues">
<div className="EquivalentValues-header">
<h5 className="EquivalentValues-title">{translate('SIDEBAR_EQUIV')}</h5>
<h5 className="EquivalentValues-title">{translate('sidebar_Equiv')}</h5>
<Select
name="equivalentValues"
// TODO: Update type
value={equivalentValues as any}
options={options as any}
onChange={this.selectOption as any}
onChange={this.selectOption}
clearable={false}
searchable={false}
/>
@ -183,11 +164,13 @@ class EquivalentValues extends React.Component<Props, State> {
{isOffline ? (
<div className="EquivalentValues-offline well well-sm">
{translate('EQUIV_VALS_OFFLINE')}
Equivalent values are unavailable offline
</div>
) : network.isTestnet ? (
<div className="text-center">
<h5 style={{ color: 'red' }}>{translate('EQUIV_VALS_TESTNET')}</h5>
<h5 style={{ color: 'red' }}>
On test network, equivalent values will not be displayed.
</h5>
</div>
) : ratesError ? (
<h5>{ratesError}</h5>
@ -226,7 +209,7 @@ class EquivalentValues extends React.Component<Props, State> {
)}
</React.Fragment>
) : (
<p>{translate('EQUIV_VALS_UNSUPPORTED_UNIT')}</p>
<p>Sorry, equivalent values are not supported for this unit.</p>
)}
</div>
)}
@ -240,7 +223,7 @@ class EquivalentValues extends React.Component<Props, State> {
const allRates = Object.values(balance).map(
value => !!rates[value.symbol] && rates[value.symbol]
);
const allEquivalentValues = allRates.map((rateType: any, i) => {
const allEquivalentValues = allRates.map((rateType, i) => {
return {
symbol: Object.keys(rates)[i],
equivalentValues: [
@ -276,9 +259,9 @@ class EquivalentValues extends React.Component<Props, State> {
// return equivalent value (unit * rate * balance)
private handleValues(unit: string, balance: Balance['wei']) {
const { rates } = this.props;
const ratesObj: Rates = { ...rates[unit] };
const ratesObj = { ...rates[unit] };
return Object.keys(ratesObj).map(key => {
const value = balance!.muln(ratesObj[key]);
const value = (balance as Wei).muln(ratesObj[key]);
return { rate: key, value };
});
}
@ -305,8 +288,7 @@ class EquivalentValues extends React.Component<Props, State> {
const currencies = tokenBalances
.filter(tk => !tk.balance.isZero())
.map(tk => tk.symbol)
.sort()
.concat([props.network.unit]);
.sort();
// If it's the same currencies as we have, skip it
if (this.requestedCurrencies && currencies.join() === this.requestedCurrencies.join()) {

View File

@ -0,0 +1,17 @@
import React from 'react';
import { Link } from 'react-router-dom';
import BityLogo from 'assets/images/logo-bity-white.svg';
export const Bity: React.SFC = () => (
<Link className="Promos-promo Promos-Bity" target="_blank" rel="noopener noreferrer" to="/swap">
<div className="Promos-promo-inner">
<div className="Promos-promo-text">
<p>Its now easier to get more ETH</p>
<h5>Swap BTC &lt;-&gt; ETH</h5>
</div>
<div className="Promos-promo-images">
<img src={BityLogo} />
</div>
</div>
</Link>
);

View File

@ -1,15 +1,12 @@
import React from 'react';
import CoinbaseLogo from 'assets/images/logo-coinbase.svg';
import { NewTabLink } from 'components/ui';
interface Props {
address: string;
}
export const Coinbase: React.SFC<Props> = ({ address }) => (
<NewTabLink
className="Promos-promo Promos--coinbase"
href={`https://buy.coinbase.com?code=60c05061-3a76-57be-b1cd-a7afa97bcb8c&address=${address}&crypto_currency=ETH&currency=USD`}
export const Coinbase: React.SFC = () => (
<a
className="Promos-promo Promos-Coinbase"
target="_blank"
rel="noopener noreferrer"
href="https://buy.coinbase.com?code=60c05061-3a76-57be-b1cd-a7afa97bcb8c&address=0xA7DeFf12461661212734dB35AdE9aE7d987D648c&crypto_currency=ETH&currency=USD"
>
<div className="Promos-promo-inner">
<div className="Promos-promo-text">
@ -17,8 +14,8 @@ export const Coinbase: React.SFC<Props> = ({ address }) => (
<h5 key="2">Buy ETH with USD</h5>
</div>
<div className="Promos-promo-images">
<img src={CoinbaseLogo} alt="Coinbase logo" />
<img src={CoinbaseLogo} />
</div>
</div>
</NewTabLink>
</a>
);

View File

@ -5,14 +5,17 @@ import ledgerLogo from 'assets/images/logo-ledger.svg';
import trezorLogo from 'assets/images/logo-trezor.svg';
export const HardwareWallets: React.SFC = () => (
<HelpLink className="Promos-promo Promos--hardware" article={HELP_ARTICLE.PROTECT_YOUR_FUNDS}>
<HelpLink
className="Promos-promo Promos-HardwareWallets"
article={HELP_ARTICLE.PROTECT_YOUR_FUNDS}
>
<div className="Promos-promo-inner">
<div className="Promos-promo-text">
<h6>Learn more about protecting your funds.</h6>
</div>
<div className="Promos-promo-images">
<img src={ledgerLogo} alt="Ledger Logo" />
<img src={trezorLogo} alt="Trezor Logo" />
<img src={ledgerLogo} />
<img src={trezorLogo} />
</div>
</div>
</HelpLink>

View File

@ -1,20 +0,0 @@
import React from 'react';
import { Link } from 'react-router-dom';
import ShapeshiftLogo from 'assets/images/logo-shapeshift.svg';
export const Shapeshift: React.SFC = () => (
<Link className="Promos-promo Promos--shapeshift" to="/swap">
<div className="Promos-promo-inner">
<div className="Promos-promo-text">
<h5>
Exchange Coins
<br />
& Tokens with
</h5>
</div>
<div className="Promos-promo-images">
<img src={ShapeshiftLogo} alt="Shapeshift Logo" />
</div>
</div>
</Link>
);

View File

@ -1,3 +1,3 @@
export * from './HardwareWallets';
export * from './Coinbase';
export * from './Shapeshift';
export * from './Bity';

View File

@ -9,6 +9,18 @@
overflow: hidden;
}
&-Bity {
background-color: #006e79;
}
&-Coinbase {
background-color: #2b71b1;
}
&-HardwareWallets {
background-color: #6e9a3e;
}
&-promo {
position: relative;
height: inherit;
@ -30,18 +42,19 @@
position: absolute;
display: flex;
align-items: center;
justify-content: center;
top: 50%;
left: 0;
width: 100%;
transform: translateY(-50%);
padding: 0 $space;
}
&-text,
&-images {
padding: 0 $space-sm;
}
&-text {
flex: 5;
padding-right: $space-xs;
max-width: 220px;
flex: 1;
p,
h4,
@ -60,15 +73,15 @@
}
&-images {
flex: 3;
max-width: 108px;
padding-left: $space-xs;
padding: 0 $space * 1.5;
img {
display: block;
margin: 0 auto;
width: 100%;
max-width: 96px;
height: auto;
padding: $space-xs;
}
}
}
@ -85,6 +98,7 @@
height: 12px;
border: 3px solid $gray-lightest;
border-radius: 100%;
outline: none;
opacity: 0.6;
&.is-active {
@ -92,23 +106,6 @@
}
}
}
// Per-promo customizations
&--shapeshift {
background-color: #263a52;
.Promos-promo-images {
max-width: 130px;
}
}
&--coinbase {
background-color: #2b71b1;
}
&--hardware {
background-color: #6e9a3e;
}
}
.carousel-exit {

View File

@ -1,30 +1,22 @@
import React from 'react';
import { TransitionGroup, CSSTransition } from 'react-transition-group';
import { HardwareWallets, Coinbase, Shapeshift } from './PromoComponents';
import { HardwareWallets, Coinbase, Bity } from './PromoComponents';
import './Promos.scss';
import { connect } from 'react-redux';
import { AppState } from '../../reducers';
const CarouselAnimation = ({ children, ...props }: any) => (
const promos = [HardwareWallets, Coinbase, Bity];
const CarouselAnimation = ({ children, ...props }) => (
<CSSTransition {...props} timeout={300} classNames="carousel">
{children}
</CSSTransition>
);
// Don't change Coinbase index
const promos = [HardwareWallets, Coinbase, Shapeshift];
interface State {
activePromo: number;
}
interface StateProps {
wallet: AppState['wallet']['inst'];
}
class PromosClass extends React.PureComponent<StateProps, State> {
export default class Promos extends React.PureComponent<{}, State> {
public timer: any = null;
public promos = [HardwareWallets, Coinbase, Shapeshift];
public state = {
activePromo: parseInt(String(Math.random() * promos.length), 10)
@ -38,27 +30,17 @@ class PromosClass extends React.PureComponent<StateProps, State> {
clearInterval(this.timer);
}
public getPromo() {
const { activePromo } = this.state;
const { wallet } = this.props;
if (activePromo === 1) {
if (wallet) {
return <Coinbase address={wallet.getAddressString()} />;
} else {
return <Shapeshift />;
}
} else {
return promos[activePromo];
}
}
public render() {
const { activePromo } = this.state;
return (
<div className="Promos">
<TransitionGroup className="Promos-promo-wrapper">
<CarouselAnimation key={Math.random()}>{this.getPromo()}</CarouselAnimation>
{promos
.filter(i => {
return i === promos[activePromo];
})
.map(promo => <CarouselAnimation key={Math.random()}>{promo}</CarouselAnimation>)}
</TransitionGroup>
<div className="Promos-nav">
{promos.map((_, index) => {
@ -86,11 +68,3 @@ class PromosClass extends React.PureComponent<StateProps, State> {
this.setState({ activePromo });
};
}
function mapStateToProps(state: AppState): StateProps {
return {
wallet: state.wallet.inst
};
}
export default connect(mapStateToProps, {})(PromosClass);

View File

@ -1,4 +1,4 @@
@import 'common/sass/variables';
@import "common/sass/variables";
.AddCustom {
&-field {
@ -11,20 +11,23 @@
&-buttons {
padding-top: 10px;
display: flex;
justify-content: center;
flex-wrap: wrap;
&-help {
text-align: center;
display: block;
font-size: 13px;
margin-bottom: 10px;
}
&-btn {
padding: 0.5rem 1.5rem;
margin: 0.25rem 0.5rem;
margin-right: 10px;
&.btn-primary {
width: 120px;
}
&.btn-default {
width: 110px;
}
}
}
}

View File

@ -1,8 +1,9 @@
import React from 'react';
import classnames from 'classnames';
import { HELP_ARTICLE } from 'config';
import { isPositiveIntegerOrZero, isValidETHAddress } from 'libs/validators';
import translate, { translateRaw } from 'translations';
import { HelpLink, Input } from 'components/ui';
import translate from 'translations';
import { HelpLink } from 'components/ui';
import './AddCustomTokenForm.scss';
import { Token } from 'types/network';
@ -41,23 +42,24 @@ export default class AddCustomTokenForm extends React.PureComponent<Props, State
public render() {
const { address, symbol, decimal } = this.state;
const inputClasses = 'AddCustom-field-input form-control input-sm';
const errors = this.getErrors();
const fields = [
{
name: 'symbol',
value: symbol,
label: translateRaw('TOKEN_SYMBOL')
label: translate('TOKEN_Symbol')
},
{
name: 'address',
value: address,
label: translateRaw('TOKEN_ADDR')
label: translate('TOKEN_Addr')
},
{
name: 'decimal',
value: decimal,
label: translateRaw('TOKEN_DEC')
label: translate('TOKEN_Dec')
}
];
@ -66,11 +68,12 @@ export default class AddCustomTokenForm extends React.PureComponent<Props, State
{fields.map(field => {
return (
<label className="AddCustom-field form-group" key={field.name}>
<div className="input-group-header">{field.label}</div>
<Input
className={`${
errors[field.name] ? 'invalid' : field.value ? 'valid' : ''
} input-group-input-small`}
<span className="AddCustom-field-label">{field.label}</span>
<input
className={classnames(
inputClasses,
errors[field.name] ? 'is-invalid' : field.value ? 'is-valid' : ''
)}
type="text"
name={field.name}
value={field.value}
@ -83,21 +86,21 @@ export default class AddCustomTokenForm extends React.PureComponent<Props, State
);
})}
<HelpLink article={HELP_ARTICLE.ADDING_NEW_TOKENS} className="AddCustom-buttons-help">
{translate('ADD_CUSTOM_TKN_HELP')}
</HelpLink>
<div className="AddCustom-buttons">
<button
className="AddCustom-buttons-btn btn btn-sm btn-default"
onClick={this.props.toggleForm}
>
{translate('ACTION_2')}
</button>
<HelpLink article={HELP_ARTICLE.ADDING_NEW_TOKENS} className="AddCustom-buttons-help">
{translate('Need help? Learn how to add custom tokens.')}
</HelpLink>
<button
className="AddCustom-buttons-btn btn btn-primary btn-sm"
disabled={!this.isValid()}
>
{translate('X_SAVE')}
{translate('x_Save')}
</button>
<button
className="AddCustom-buttons-btn btn btn-sm btn-default"
onClick={this.props.toggleForm}
>
{translate('x_Cancel')}
</button>
</div>
</form>

View File

@ -15,23 +15,19 @@ interface Props {
onRemoveCustomToken(symbol: string): any;
}
interface TrackedTokens {
[symbol: string]: boolean;
}
interface State {
trackedTokens: { [symbol: string]: boolean };
showCustomTokenForm: boolean;
}
export default class TokenBalances extends React.PureComponent<Props, State> {
public state: State = {
public state = {
trackedTokens: {},
showCustomTokenForm: false
};
public componentWillReceiveProps(nextProps: Props) {
if (nextProps.tokenBalances !== this.props.tokenBalances) {
const trackedTokens = nextProps.tokenBalances.reduce<TrackedTokens>((prev, t) => {
const trackedTokens = nextProps.tokenBalances.reduce((prev, t) => {
prev[t.symbol] = !t.balance.isZero();
return prev;
}, {});
@ -50,9 +46,11 @@ export default class TokenBalances extends React.PureComponent<Props, State> {
bottom = (
<div className="TokenBalances-buttons">
<button className="btn btn-primary btn-block" onClick={this.handleSetWalletTokens}>
<span>{translate('X_SAVE')}</span>
<span>{translate('x_Save')}</span>
</button>
<p className="TokenBalances-buttons-help">{translate('PROMPT_ADD_CUSTOM_TKN')}</p>
<p className="TokenBalances-buttons-help">
{translate('Missing tokens? You can add custom tokens next.')}
</p>
</div>
);
} else if (showCustomTokenForm) {
@ -69,10 +67,10 @@ export default class TokenBalances extends React.PureComponent<Props, State> {
bottom = (
<div className="TokenBalances-buttons">
<button className="btn btn-default btn-xs" onClick={this.toggleShowCustomTokenForm}>
<span>{translate('SEND_CUSTOM')}</span>
</button>
<span>{translate('SEND_custom')}</span>
</button>{' '}
<button className="btn btn-default btn-xs" onClick={this.props.scanWalletForTokens}>
<span>{translate('SCAN_TOKENS')}</span>
<span>Scan for New Tokens</span>
</button>
</div>
);
@ -103,7 +101,7 @@ export default class TokenBalances extends React.PureComponent<Props, State> {
</tbody>
</table>
) : (
<div className="well well-sm text-center">{translate('SCAN_TOKENS_FAIL_NO_TOKENS')}</div>
<div className="well well-sm text-center">No tokens found</div>
)}
{bottom}
</div>

View File

@ -54,7 +54,6 @@ export default class TokenRow extends React.PureComponent<Props, State> {
{!!custom && (
<img
src={removeIcon}
alt="Remove"
className="TokenRow-symbol-remove"
title="Remove Token"
onClick={this.onRemove}

View File

@ -1,4 +1,4 @@
@import 'common/sass/variables';
@import "common/sass/variables";
.TokenBalances {
&-title {
@ -34,12 +34,6 @@
}
&-buttons {
display: flex;
flex-wrap: wrap;
justify-content: center;
& > &-btn {
margin: 0.25rem 0.5rem;
}
&-help {
padding-top: 10px;
text-align: center;

View File

@ -74,7 +74,7 @@ class TokenBalances extends React.Component<Props> {
className="TokenBalances-scan btn btn-primary btn-block"
onClick={this.scanWalletForTokens}
>
{translate('SCAN_TOKENS')}
{translate('Scan for my Tokens')}
</button>
);
} else {
@ -95,7 +95,7 @@ class TokenBalances extends React.Component<Props> {
return (
<section className="TokenBalances">
<h5 className="TokenBalances-title">{translate('SIDEBAR_TOKENBAL')}</h5>
<h5 className="TokenBalances-title">{translate('sidebar_TokenBal')}</h5>
{content}
</section>
);

Some files were not shown because too many files have changed in this diff Show More