Expand https -> ws connection info (#749)

* Expand https -> ws connection info

* Update NodeInfo.tsx

* Update Connecting.tsx

* Remove apps--App (& Content/SideBar flex embedded)
This commit is contained in:
Jaco Greeff 2019-02-22 08:11:08 +01:00 committed by GitHub
parent 4a1dacd239
commit 03d7865047
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 192 additions and 164 deletions

View File

@ -0,0 +1,68 @@
// Copyright 2017-2019 @polkadot/apps authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { I18nProps } from '@polkadot/ui-app/types';
import { ApiProps } from '@polkadot/ui-api/types';
import React from 'react';
import styled from 'styled-components';
import { withApi, withMulti } from '@polkadot/ui-api/index';
import settings from '@polkadot/ui-settings';
import translate from './translate';
type Props = I18nProps & ApiProps;
const Wrapper = styled.div`
background: red;
color: white;
bottom: 0;
left: 0;
line-height: 1.5em;
opacity: 0.9;
padding: 1em 5em;
position: fixed;
right: 0;
text-align: center;
`;
// @ts-ignore
const isFirefox = typeof InstallTrigger !== 'undefined';
class Connecting extends React.PureComponent<Props> {
render () {
const { isApiConnected, t } = this.props;
if (isApiConnected) {
return null;
}
const wsUrl = settings.apiUrl;
const isWs = wsUrl.indexOf('ws://') === 0;
const isWsRemote = wsUrl.indexOf('127.0.0.1') === -1;
const isHttps = window.location.protocol.indexOf('https:') === 0;
return (
<Wrapper>
<div>{t('You are not connected to a node. Ensure that your node is running and that the Websocket endpoint is reachable.')}</div>
{
isFirefox && isWs
? <div>{t('With the Firefox browser connecting to insecure WebSockets ({{wsUrl}}) will fail due to the browser not allowing localhost access from a secure site.', { replace: { wsUrl } })}</div>
: undefined
}
{
isWs && isWsRemote && isHttps
? <div>{t(`You are connecting from a secure location to an insecure WebSocket ({{wsUrl}}). Due to browser mixed-content security policies this connection type is not allowed. Change the RPC service to a secure 'wss' endpoint.`, { replace: { wsUrl } })}</div>
: undefined
}
</Wrapper>
);
}
}
export default withMulti(
Connecting,
translate,
withApi
);

View File

@ -1,18 +0,0 @@
/* Copyright 2017-2019 @polkadot/apps authors & contributors
/* This software may be modified and distributed under the terms
/* of the Apache-2.0 license. See the LICENSE file for details. */
.apps--Connecting {
bottom: 0;
left: 0;
position: fixed;
right: 0;
text-align: center;
}
.apps--Connecting-text {
background: red;
color: white;
line-height: 1.5em;
padding: 1em 2em;
}

View File

@ -1,52 +0,0 @@
// Copyright 2017-2019 @polkadot/apps authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { I18nProps } from '@polkadot/ui-app/types';
import { ApiProps } from '@polkadot/ui-api/types';
import './Connecting.css';
import React from 'react';
import { withApi, withMulti } from '@polkadot/ui-api/index';
import settings from '@polkadot/ui-settings';
import translate from '../translate';
type Props = I18nProps & ApiProps;
// @ts-ignore
const isFirefox = typeof InstallTrigger !== 'undefined';
class Connecting extends React.PureComponent<Props> {
render () {
const { isApiConnected, t } = this.props;
if (isApiConnected) {
return null;
}
return (
<div className='apps--Connecting'>
<div className='apps--Connecting-text'>
{t('You are not connected to a node. Ensure that your node is running and that the Websocket endpoint is reachable.')}&nbsp;
{
isFirefox && settings.apiUrl.indexOf('ws://') === 0
? t('With the Firefox browser connecting to insecure WebSockets (in this case {{url}}) will fail due to the browser not allowing localhost access from a secure site.', {
replace: {
url: settings.apiUrl
}
})
: ''
}
</div>
</div>
);
}
}
export default withMulti(
Connecting,
translate,
withApi
);

View File

@ -1,17 +0,0 @@
/* Copyright 2017-2019 @polkadot/apps authors & contributors
/* This software may be modified and distributed under the terms
/* of the Apache-2.0 license. See the LICENSE file for details. */
.apps--Content {
background: white;
height: 100%;
width: 100%;
}
.apps--Content-Frame {
border: none;
box-sizing: border-box;
height: 100%;
overflow-y: scroll;
width: 100%;
}

View File

@ -14,7 +14,7 @@ import { withCall, withMulti, withObservable } from '@polkadot/ui-api/index';
import { stringToU8a } from '@polkadot/util';
import { xxhashAsHex } from '@polkadot/util-crypto';
import translate from './translate';
import translate from '../translate';
type Props = I18nProps & {
optionsAll?: KeyringOptions,

View File

@ -6,14 +6,13 @@ import { I18nProps } from '@polkadot/ui-app/types';
import { ApiProps } from '@polkadot/ui-api/types';
import { QueueProps } from '@polkadot/ui-app/Status/types';
import './Content.css';
import React from 'react';
import { withRouter } from 'react-router';
import styled from 'styled-components';
import { withCalls, withMulti } from '@polkadot/ui-api/index';
import { QueueConsumer } from '@polkadot/ui-app/Status/Context';
import Status from '../Status';
import Status from './Status';
import routing from '../routing';
import translate from '../translate';
import NotFound from './NotFound';
@ -22,6 +21,18 @@ type Props = I18nProps & ApiProps & {
location: Location
};
const Wrapper = styled.div`
background: #fafafa;
display: flex;
flex-direction: column;
flex-grow: 1;
height: 100%;
min-height: 100vh;
overflow-x: hidden;
overflow-y: auto;
width: 100%;
`;
const unknown = {
display: {
needsApi: undefined
@ -40,14 +51,14 @@ class Content extends React.Component<Props> {
if (needsApi && (!isApiReady || !isApiConnected)) {
return (
<div className='apps--Content-body'>
<Wrapper>
<main>{t('Waiting for API to be connected and ready.')}</main>
</div>
</Wrapper>
);
}
return (
<div className='apps--Content'>
<Wrapper>
<QueueConsumer>
{({ queueAction, stqueue, txqueue }: QueueProps) => (
<>
@ -64,7 +75,7 @@ class Content extends React.Component<Props> {
</>
)}
</QueueConsumer>
</div>
</Wrapper>
);
}
}

View File

@ -6,14 +6,38 @@ import { ApiProps } from '@polkadot/ui-api/types';
import { BareProps } from '@polkadot/ui-app/types';
import React from 'react';
import styled from 'styled-components';
import { withApi } from '@polkadot/ui-api/with';
import { BestNumber, Chain, NodeName, NodeVersion } from '@polkadot/ui-reactive/index';
type Props = ApiProps & BareProps & {};
const Wrapper = styled.div`
background: transparent;
color: white;
font-size: 0.75rem;
opacity: 0.5;
padding: 0 1.5rem 0 0;
text-align: right;
> div {
margin-bottom: -0.125em;
> div {
display: inline-block;
}
&.spacer {
margin-bottom: 0.5rem;
}
}
.rx--updated {
background: inherit !important;
}
`;
const HEALTH_POLL = 22500;
const pkgJson = require('../package.json');
const pkgJson = require('../../package.json');
class NodeInfo extends React.PureComponent<Props> {
componentDidMount () {
@ -33,19 +57,19 @@ class NodeInfo extends React.PureComponent<Props> {
const uiInfo = `@polkadot/apps v${pkgJson.version}`;
return (
<div className='apps--NodeInfo'>
<div className='apps--NodeInfo-inline'>
<Wrapper>
<div>
<Chain />&nbsp;
<BestNumber label='#' />
</div>
<div className='apps--NodeInfo-inline'>
<div>
<NodeName />&nbsp;
<NodeVersion label='v' />
</div>
<div className='spacer' />
<div>{api.libraryInfo}</div>
<div>{uiInfo}</div>
</div>
</Wrapper>
);
}
}

View File

@ -7,7 +7,10 @@
.apps--SideBar {
background: #4e4e4e;
display: flex;
flex-direction: column;
flex-shrink: 0;
min-height: 100vh;
padding: 0.75em 0 0 0.75em;
position: relative;
text-align: left;

View File

@ -13,11 +13,10 @@ import { Button, Icon, Menu } from '@polkadot/ui-app/index';
import routing from '../routing';
import translate from '../translate';
import Item from './Item';
import NodeInfo from './NodeInfo';
import getLogo from './logos';
type Props = I18nProps & {
children?: React.ReactNode
};
type Props = I18nProps;
type State = {
isCollapsed: boolean
@ -37,7 +36,6 @@ class SideBar extends React.PureComponent<Props, State> {
}
render () {
const { children } = this.props;
const { isCollapsed } = this.state;
return (
@ -55,7 +53,7 @@ class SideBar extends React.PureComponent<Props, State> {
{
isCollapsed
? null
: children
: <NodeInfo />
}
{this.renderCollapse()}
</Menu>

View File

@ -0,0 +1,57 @@
// Copyright 2017-2019 @polkadot/apps authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
// Unused atm, experiment as a replacement for NodeInfo on the SideBar
import React from 'react';
import styled from 'styled-components';
import { BestNumber, Chain, NodeName, NodeVersion } from '@polkadot/ui-reactive/index';
type Props = {};
const Wrapper = styled.div`
background: #f2f2f2;
font-size: 0.85rem;
line-height: 1rem;
overflow: hidden;
padding: 0.5rem 1rem;
position: fixed;
right: 0;
text-align: right;
text-overflow: ellipsis;
white-space: nowrap;
top: 0;
div {
display: inline-block;
vertical-align: middle;
}
> div {
border-left: 1px solid #ccc;
padding: 0 0.5rem;
&:first-child {
border-width: 0;
}
}
`;
export default class TopBar extends React.PureComponent<Props> {
render () {
return (
<Wrapper>
<div>
<NodeName />&nbsp;
<NodeVersion label='v' />
</div>
<div>
<Chain />&nbsp;
<BestNumber label='#' />
</div>
</Wrapper>
);
}
}

View File

@ -1,49 +0,0 @@
/* Copyright 2017-2019 @polkadot/apps authors & contributors
/* This software may be modified and distributed under the terms
/* of the Apache-2.0 license. See the LICENSE file for details. */
.apps--App {
align-items: stretch;
box-sizing: border-box;
display: flex;
min-height: 100vh;
.apps--Content,
.apps--SideBar {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.apps--Content {
background: #fafafa /* #fff */;
flex-grow: 1;
overflow-x: hidden;
overflow-y: auto;
}
}
.apps--NodeInfo {
background: transparent;
color: white;
font-size: 0.75rem;
opacity: 0.5;
padding: 0 1.5rem 0 0;
text-align: right;
> div {
margin-bottom: -0.125em;
&.spacer {
margin-bottom: 0.5rem;
}
}
div.rx--updated {
background: inherit !important;
}
}
.apps--NodeInfo-inline > div {
display: inline-block;
}

View File

@ -4,10 +4,9 @@
import { BareProps } from '@polkadot/ui-app/types';
import './index.css';
import React from 'react';
import store from 'store';
import styled from 'styled-components';
import { typeRegistry } from '@polkadot/types';
import createApp from '@polkadot/ui-app/index';
import { classes } from '@polkadot/ui-app/util';
@ -16,22 +15,26 @@ import settings from '@polkadot/ui-settings';
import Connecting from './Connecting';
import Content from './Content';
import NodeInfo from './NodeInfo';
import SideBar from './SideBar';
type Props = BareProps & {};
const Wrapper = styled.div`
align-items: stretch;
box-sizing: border-box;
display: flex;
min-height: 100vh;
`;
function App (props: Props) {
return (
<div className={classes(`theme--${settings.uiTheme}`, 'apps--App')}>
<SideBar>
<NodeInfo />
</SideBar>
<Wrapper className={classes(`theme--${settings.uiTheme}`)}>
<SideBar />
<Signer>
<Content />
</Signer>
<Connecting />
</div>
</Wrapper>
);
}

View File

@ -16,7 +16,7 @@ type Props = BareProps & CallProps & {
class NodeVersion extends React.PureComponent<Props> {
render () {
const { children, className, label = '', style, system_version = 'unknown' } = this.props;
const { children, className, label = '', style, system_version = '-' } = this.props;
return (
<div