Mobile CSS Improvements (#525)
* Banner announcement cuts off mailchimp on mobile * Hide site version on mobile. Added version to footer as well in case someone _really_ needs to check it. * Shrink pre-footer font size on mobile. * Fix column breakpoint for force offline send (Was stacking, now remains side-by-side.) * Reduce header dropdown sizes at mobile. Force gas dropdown to the left side so its not offscreen. * Columnify contracts for better mobile behavior and less code. * Remove leftover string interpolation * Better mobile header / nav sizing.
This commit is contained in:
parent
69a63d8731
commit
8f878abab1
|
@ -1,8 +1,5 @@
|
|||
import React from 'react';
|
||||
import {
|
||||
forceOfflineConfig as dForceOfflineConfig,
|
||||
TForceOfflineConfig
|
||||
} from 'actions/config';
|
||||
import { forceOfflineConfig as dForceOfflineConfig, TForceOfflineConfig } from 'actions/config';
|
||||
import OfflineSymbol from 'components/ui/OfflineSymbol';
|
||||
import { connect } from 'react-redux';
|
||||
import { AppState } from 'reducers';
|
||||
|
@ -24,10 +21,10 @@ class OfflineToggle extends React.Component<OfflineToggleProps, {}> {
|
|||
<div>
|
||||
{!offline ? (
|
||||
<div className="row text-center">
|
||||
<div className="col-md-3">
|
||||
<div className="col-xs-3">
|
||||
<OfflineSymbol offline={offline || forceOffline} size={size} />
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<div className="col-xs-6">
|
||||
<button className="btn-xs btn-info" onClick={forceOfflineConfig}>
|
||||
{forceOffline ? 'Go Online' : 'Go Offline'}
|
||||
</button>
|
||||
|
|
|
@ -6,7 +6,12 @@
|
|||
margin-top: 5rem;
|
||||
background-color: white;
|
||||
text-align: center;
|
||||
|
||||
p {
|
||||
font-size: $font-size-medium;
|
||||
|
||||
@media screen and (max-width: $screen-sm) {
|
||||
font-size: $font-size-small;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@ import {
|
|||
ledgerReferralURL,
|
||||
trezorReferralURL,
|
||||
bitboxReferralURL,
|
||||
donationAddressMap
|
||||
donationAddressMap,
|
||||
VERSION
|
||||
} from 'config/data';
|
||||
import React from 'react';
|
||||
import translate from 'translations';
|
||||
|
@ -120,9 +121,7 @@ export default class Footer extends React.Component<Props, State> {
|
|||
};
|
||||
|
||||
public render() {
|
||||
const buttons: IButton[] = [
|
||||
{ text: 'Okay', type: 'default', onClick: this.closeModal }
|
||||
];
|
||||
const buttons: IButton[] = [{ text: 'Okay', type: 'default', onClick: this.closeModal }];
|
||||
return (
|
||||
<div>
|
||||
<PreFooter />
|
||||
|
@ -159,66 +158,59 @@ export default class Footer extends React.Component<Props, State> {
|
|||
<p>
|
||||
<b>Be safe & secure: </b>
|
||||
<NewTabLink href="https://myetherwallet.groovehq.com/knowledge_base/topics/protecting-yourself-and-your-funds">
|
||||
We highly recommend that you read our guide on How to Prevent
|
||||
Loss & Theft for some recommendations on how to be proactive
|
||||
about your security.
|
||||
We highly recommend that you read our guide on How to Prevent Loss & Theft for
|
||||
some recommendations on how to be proactive about your security.
|
||||
</NewTabLink>
|
||||
</p>
|
||||
<p>
|
||||
<b>Always backup your keys: </b>
|
||||
MyEtherWallet.com & MyEtherWallet CX are not "web wallets". You
|
||||
do not create an account or give us your funds to hold onto. No
|
||||
data leaves your computer / your browser. We make it easy for
|
||||
you to create, save, and access your information and interact
|
||||
with the blockchain.
|
||||
MyEtherWallet.com & MyEtherWallet CX are not "web wallets". You do not create an
|
||||
account or give us your funds to hold onto. No data leaves your computer / your
|
||||
browser. We make it easy for you to create, save, and access your information and
|
||||
interact with the blockchain.
|
||||
</p>
|
||||
<p>
|
||||
<b>We are not responsible for any loss: </b>
|
||||
Ethereum, MyEtherWallet.com & MyEtherWallet CX, and some of the
|
||||
underlying Javascript libraries we use are under active
|
||||
development. While we have thoroughly tested & tens of thousands
|
||||
of wallets have been successfully created by people all over the
|
||||
globe, there is always the possibility something unexpected
|
||||
happens that causes your funds to be lost. Please do not invest
|
||||
more than you are willing to lose, and please be careful.
|
||||
Ethereum, MyEtherWallet.com & MyEtherWallet CX, and some of the underlying
|
||||
Javascript libraries we use are under active development. While we have thoroughly
|
||||
tested & tens of thousands of wallets have been successfully created by people all
|
||||
over the globe, there is always the possibility something unexpected happens that
|
||||
causes your funds to be lost. Please do not invest more than you are willing to
|
||||
lose, and please be careful.
|
||||
</p>
|
||||
<p>
|
||||
<b>Translations of MyEtherWallet: </b>
|
||||
The community has done an amazing job translating MyEtherWallet
|
||||
into a variety of languages. However, MyEtherWallet can only
|
||||
verify the validity and accuracy of the information provided in
|
||||
English and, because of this, the English version of our website
|
||||
is the official text.
|
||||
The community has done an amazing job translating MyEtherWallet into a variety of
|
||||
languages. However, MyEtherWallet can only verify the validity and accuracy of the
|
||||
information provided in English and, because of this, the English version of our
|
||||
website is the official text.
|
||||
</p>
|
||||
<p>
|
||||
<b>MIT License</b> Copyright © 2015-2017 MyEtherWallet LLC
|
||||
</p>
|
||||
<p>
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
software and associated documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
</p>
|
||||
<p>
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
</p>
|
||||
<b>
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</b>
|
||||
</Modal>
|
||||
<p>Latest Block#: {this.props.latestBlock}</p>
|
||||
<p>v{VERSION}</p>
|
||||
<p>© 2017 MyEtherWallet, LLC</p>
|
||||
</div>
|
||||
|
||||
|
@ -229,10 +221,7 @@ export default class Footer extends React.Component<Props, State> {
|
|||
</h5>
|
||||
<p>Consider using our affiliate links to</p>
|
||||
<ul className="Footer-affiliate-wrap">
|
||||
<AffiliateTag
|
||||
link={bityReferralURL}
|
||||
text="Swap ETH/BTC/EUR/CHF via Bity.com"
|
||||
/>
|
||||
<AffiliateTag link={bityReferralURL} text="Swap ETH/BTC/EUR/CHF via Bity.com" />
|
||||
</ul>
|
||||
<p>Buy a</p>
|
||||
<ul className="Footer-affiliate-wrap">
|
||||
|
@ -248,11 +237,7 @@ export default class Footer extends React.Component<Props, State> {
|
|||
<li>
|
||||
ETH: mewtopia.eth{' '}
|
||||
<span className="mono wrap">
|
||||
<NewTabLink
|
||||
href={`https://etherscan.io/address/${
|
||||
donationAddressMap.ETH
|
||||
}`}
|
||||
>
|
||||
<NewTabLink href={`https://etherscan.io/address/${donationAddressMap.ETH}`}>
|
||||
{donationAddressMap.ETH}
|
||||
</NewTabLink>
|
||||
</span>
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
&-dropdown-menu {
|
||||
padding: 0.5rem !important;
|
||||
min-width: 300px !important;
|
||||
|
||||
@media screen and (max-width: $screen-xs) {
|
||||
left: 0;
|
||||
right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
&-header {
|
||||
|
|
|
@ -29,7 +29,11 @@ export default class GasPriceDropdown extends Component<Props, {}> {
|
|||
}
|
||||
|
||||
private renderLabel = () => {
|
||||
return `Gas Price: ${this.props.value} Gwei`;
|
||||
return (
|
||||
<span>
|
||||
Gas Price<span className="hidden-xs">: {this.props.value} Gwei</span>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
private renderOptions = () => {
|
||||
|
@ -45,20 +49,14 @@ export default class GasPriceDropdown extends Component<Props, {}> {
|
|||
max={gasPriceDefaults.gasPriceMaxGwei}
|
||||
onChange={this.handleGasPriceChange}
|
||||
/>
|
||||
<p className="small col-xs-4 text-left GasPrice-padding-reset">
|
||||
Not So Fast
|
||||
</p>
|
||||
<p className="small col-xs-4 text-center GasPrice-padding-reset">
|
||||
Fast
|
||||
</p>
|
||||
<p className="small col-xs-4 text-right GasPrice-padding-reset">
|
||||
Fast AF
|
||||
</p>
|
||||
<p className="small col-xs-4 text-left GasPrice-padding-reset">Not So Fast</p>
|
||||
<p className="small col-xs-4 text-center GasPrice-padding-reset">Fast</p>
|
||||
<p className="small col-xs-4 text-right GasPrice-padding-reset">Fast AF</p>
|
||||
<p className="small GasPrice-description">
|
||||
Gas Price is the amount you pay per unit of gas.{' '}
|
||||
<code>TX fee = gas price * gas limit</code> & is paid to miners for
|
||||
including your TX in a block. Higher the gas price = faster
|
||||
transaction, but more expensive. Default is <code>21 GWEI</code>.
|
||||
<code>TX fee = gas price * gas limit</code> & is paid to miners for including your TX in
|
||||
a block. Higher the gas price = faster transaction, but more expensive. Default is{' '}
|
||||
<code>21 GWEI</code>.
|
||||
</p>
|
||||
<p>
|
||||
{/* TODO: maybe not hardcode a link? :) */}
|
||||
|
@ -78,9 +76,7 @@ export default class GasPriceDropdown extends Component<Props, {}> {
|
|||
this.props.onChange(parseInt(value, 10));
|
||||
};
|
||||
|
||||
private handleGasPriceChange = (
|
||||
e: React.SyntheticEvent<HTMLInputElement>
|
||||
) => {
|
||||
private handleGasPriceChange = (e: React.SyntheticEvent<HTMLInputElement>) => {
|
||||
this.updateGasPrice((e.target as HTMLInputElement).value);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -14,8 +14,9 @@
|
|||
margin-bottom: -20px;
|
||||
font-size: 0;
|
||||
white-space: nowrap;
|
||||
|
||||
@media screen and (max-width: $screen-sm) {
|
||||
margin: 0 -5% -20px;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,10 @@ $small-size: 900px;
|
|||
.Header {
|
||||
margin-bottom: 2rem;
|
||||
|
||||
@media screen and (max-width: $screen-sm) {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
&-announcement {
|
||||
padding: 4px 10px;
|
||||
line-height: 26px;
|
||||
|
@ -110,6 +114,7 @@ $small-size: 900px;
|
|||
flex: 1 auto;
|
||||
text-align: right;
|
||||
padding: 0 0 5px;
|
||||
|
||||
@include small-query {
|
||||
text-align: center;
|
||||
}
|
||||
|
@ -128,6 +133,12 @@ $small-size: 900px;
|
|||
&-dropdown {
|
||||
margin-left: 6px;
|
||||
|
||||
@media screen and (max-width: $screen-xs) {
|
||||
.btn {
|
||||
padding: .3rem .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
&-add {
|
||||
text-align: center;
|
||||
padding-top: $space-sm !important;
|
||||
|
|
|
@ -67,13 +67,8 @@ export default class Header extends Component<Props, State> {
|
|||
} = this.props;
|
||||
const { isAddingCustomNode } = this.state;
|
||||
const selectedLanguage = languageSelection;
|
||||
const selectedNetwork = getNetworkConfigFromId(
|
||||
node.network,
|
||||
customNetworks
|
||||
);
|
||||
const LanguageDropDown = Dropdown as new () => Dropdown<
|
||||
typeof selectedLanguage
|
||||
>;
|
||||
const selectedNetwork = getNetworkConfigFromId(node.network, customNetworks);
|
||||
const LanguageDropDown = Dropdown as new () => Dropdown<typeof selectedLanguage>;
|
||||
|
||||
const nodeOptions = Object.keys(NODES)
|
||||
.map(key => {
|
||||
|
@ -120,11 +115,7 @@ export default class Header extends Component<Props, State> {
|
|||
|
||||
<section className="Header-branding">
|
||||
<section className="Header-branding-inner container">
|
||||
<Link
|
||||
to="/"
|
||||
className="Header-branding-title"
|
||||
aria-label="Go to homepage"
|
||||
>
|
||||
<Link to="/" className="Header-branding-title" aria-label="Go to homepage">
|
||||
{/* TODO - don't hardcode image path*/}
|
||||
<img
|
||||
className="Header-branding-title-logo"
|
||||
|
@ -135,7 +126,7 @@ export default class Header extends Component<Props, State> {
|
|||
/>
|
||||
</Link>
|
||||
<div className="Header-branding-right">
|
||||
<span className="Header-branding-right-version">v{VERSION}</span>
|
||||
<span className="Header-branding-right-version hidden-xs">v{VERSION}</span>
|
||||
|
||||
<div className="Header-branding-right-dropdown">
|
||||
<GasPriceDropdown
|
||||
|
@ -146,9 +137,7 @@ export default class Header extends Component<Props, State> {
|
|||
|
||||
<div className="Header-branding-right-dropdown">
|
||||
<LanguageDropDown
|
||||
ariaLabel={`change language. current language ${
|
||||
languages[selectedLanguage]
|
||||
}`}
|
||||
ariaLabel={`change language. current language ${languages[selectedLanguage]}`}
|
||||
options={Object.values(languages)}
|
||||
value={languages[selectedLanguage]}
|
||||
extra={
|
||||
|
|
|
@ -13,21 +13,23 @@ export const ANNOUNCEMENT_MESSAGE = `
|
|||
This is an Alpha build of MyEtherWallet v4. Please only use for testing,
|
||||
or use v3 at <a href='https://myetherwallet.com'>https://myetherwallet.com</a>.
|
||||
<br/>
|
||||
If you're interested in recieving updates about the MyEtherWallet V4 Alpha, you can subscribe via <a href="http://myetherwallet.us16.list-manage.com/subscribe?u=afced8afb6eb2968ba407a144&id=15a7c74eab">mailchimp</a> :)
|
||||
<span class="hidden-xs">
|
||||
If you're interested in recieving updates about the MyEtherWallet V4 Alpha, you can subscribe via
|
||||
<a href="http://myetherwallet.us16.list-manage.com/subscribe?u=afced8afb6eb2968ba407a144&id=15a7c74eab">
|
||||
mailchimp
|
||||
</a>
|
||||
:)
|
||||
</span>
|
||||
`;
|
||||
|
||||
const etherScan = 'https://etherscan.io';
|
||||
const blockChainInfo = 'https://blockchain.info';
|
||||
const ethPlorer = 'https://ethplorer.io';
|
||||
|
||||
export const ETHTxExplorer = (txHash: string): string =>
|
||||
`${etherScan}/tx/${txHash}`;
|
||||
export const BTCTxExplorer = (txHash: string): string =>
|
||||
`${blockChainInfo}/tx/${txHash}`;
|
||||
export const ETHAddressExplorer = (address: string): string =>
|
||||
`${etherScan}/address/${address}`;
|
||||
export const ETHTokenExplorer = (address: string): string =>
|
||||
`${ethPlorer}/address/${address}`;
|
||||
export const ETHTxExplorer = (txHash: string): string => `${etherScan}/tx/${txHash}`;
|
||||
export const BTCTxExplorer = (txHash: string): string => `${blockChainInfo}/tx/${txHash}`;
|
||||
export const ETHAddressExplorer = (address: string): string => `${etherScan}/address/${address}`;
|
||||
export const ETHTokenExplorer = (address: string): string => `${ethPlorer}/address/${address}`;
|
||||
|
||||
export const donationAddressMap = {
|
||||
BTC: '1MEWT2SGbqtz6mPCgFcnea8XmWV5Z4Wc6',
|
||||
|
@ -41,8 +43,7 @@ export const gasPriceDefaults = {
|
|||
};
|
||||
|
||||
export const bityReferralURL = 'https://bity.com/af/jshkb37v';
|
||||
export const ledgerReferralURL =
|
||||
'https://www.ledgerwallet.com/r/fa4b?path=/products/';
|
||||
export const ledgerReferralURL = 'https://www.ledgerwallet.com/r/fa4b?path=/products/';
|
||||
export const trezorReferralURL = 'https://trezor.io/?a=myetherwallet.com';
|
||||
export const bitboxReferralURL = 'https://digitalbitbox.com/?ref=mew';
|
||||
|
||||
|
@ -286,9 +287,7 @@ export async function initWeb3Node(): Promise<void> {
|
|||
}
|
||||
|
||||
if (networkId === 'loading') {
|
||||
throw new Error(
|
||||
'MetaMask / Mist is still loading. Please refresh the page and try again.'
|
||||
);
|
||||
throw new Error('MetaMask / Mist is still loading. Please refresh the page and try again.');
|
||||
}
|
||||
|
||||
NODES.web3 = {
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
.InteractForm {
|
||||
&-address {
|
||||
display: flex;
|
||||
|
||||
> * {
|
||||
flex: 1;
|
||||
margin-right: 10px;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
import React, { Component } from 'react';
|
||||
import translate from 'translations';
|
||||
import './InteractForm.scss';
|
||||
import { NetworkContract } from 'config/data';
|
||||
import { getNetworkContracts } from 'selectors/config';
|
||||
import { connect } from 'react-redux';
|
||||
|
@ -65,26 +64,22 @@ e":"a", "type":"uint256"}], "name":"foo", "outputs": [] }]';
|
|||
// TODO: Use common components for address, abi json
|
||||
return (
|
||||
<div className="InteractForm">
|
||||
<div className="InteractForm-address">
|
||||
<label className="InteractForm-address-field form-group">
|
||||
<div className="InteractForm-address row">
|
||||
<label className="InteractForm-address-field form-group col-sm-6">
|
||||
<h4>{translate('CONTRACT_Title')}</h4>
|
||||
<input
|
||||
placeholder="mewtopia.eth or 0x7cB57B5A97eAbe94205C07890BE4c1aD31E486A8"
|
||||
name="contract_address"
|
||||
autoComplete="off"
|
||||
value={address}
|
||||
className={classnames(
|
||||
'InteractForm-address-field-input',
|
||||
'form-control',
|
||||
{
|
||||
'is-invalid': !validEthAddress
|
||||
}
|
||||
)}
|
||||
className={classnames('InteractForm-address-field-input', 'form-control', {
|
||||
'is-invalid': !validEthAddress
|
||||
})}
|
||||
onChange={this.handleInput('address')}
|
||||
/>
|
||||
</label>
|
||||
|
||||
<label className="InteractForm-address-contract form-group">
|
||||
<label className="InteractForm-address-contract form-group col-sm-6">
|
||||
<h4>{translate('CONTRACT_Title_2')}</h4>
|
||||
<select
|
||||
className="InteractForm-address-field-input form-control"
|
||||
|
@ -102,19 +97,13 @@ e":"a", "type":"uint256"}], "name":"foo", "outputs": [] }]';
|
|||
|
||||
<div className="InteractForm-interface">
|
||||
<label className="InteractForm-interface-field form-group">
|
||||
<h4 className="InteractForm-interface-field-label">
|
||||
{translate('CONTRACT_Json')}
|
||||
</h4>
|
||||
<h4 className="InteractForm-interface-field-label">{translate('CONTRACT_Json')}</h4>
|
||||
<textarea
|
||||
placeholder={this.abiJsonPlaceholder}
|
||||
name="abiJson"
|
||||
className={classnames(
|
||||
'InteractForm-interface-field-input',
|
||||
'form-control',
|
||||
{
|
||||
'is-invalid': !validAbiJson
|
||||
}
|
||||
)}
|
||||
className={classnames('InteractForm-interface-field-input', 'form-control', {
|
||||
'is-invalid': !validAbiJson
|
||||
})}
|
||||
onChange={this.handleInput('abiJson')}
|
||||
value={abiJson}
|
||||
rows={6}
|
||||
|
|
Loading…
Reference in New Issue