diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json
index 92540ea6..36b78e79 100644
--- a/client/src/__locales/en.json
+++ b/client/src/__locales/en.json
@@ -249,5 +249,7 @@
"update_announcement": "AdGuard Home {{version}} is now available! <0>Click here0> for more info.",
"upstream_parallel": "Use parallel queries to speed up resolving by simultaneously querying all upstream servers",
"bootstrap_dns": "Bootstrap DNS servers",
- "bootstrap_dns_desc": "Bootstrap DNS servers are used to resolve IP addresses of the DOH/DOT resolvers you specify as upstreams."
+ "bootstrap_dns_desc": "Bootstrap DNS servers are used to resolve IP addresses of the DOH/DOT resolvers you specify as upstreams.",
+ "setup_guide": "Setup guide",
+ "dns_addresses": "DNS addresses"
}
diff --git a/client/src/components/App/index.js b/client/src/components/App/index.js
index 91c5e512..a2676dd0 100644
--- a/client/src/components/App/index.js
+++ b/client/src/components/App/index.js
@@ -14,8 +14,9 @@ import Dashboard from '../../containers/Dashboard';
import Settings from '../../containers/Settings';
import Filters from '../../containers/Filters';
import Logs from '../../containers/Logs';
-import Footer from '../ui/Footer';
+import SetupGuide from '../../containers/SetupGuide';
import Toasts from '../Toasts';
+import Footer from '../ui/Footer';
import Status from '../ui/Status';
import UpdateTopline from '../ui/UpdateTopline';
import EncryptionTopline from '../ui/EncryptionTopline';
@@ -86,6 +87,7 @@ class App extends Component {
+
}
diff --git a/client/src/components/Header/Header.css b/client/src/components/Header/Header.css
index dbbcf08d..a8273e78 100644
--- a/client/src/components/Header/Header.css
+++ b/client/src/components/Header/Header.css
@@ -76,6 +76,13 @@
font-weight: 600;
}
+.nav-version__link {
+ position: relative;
+ display: inline-block;
+ border-bottom: 1px dashed #495057;
+ cursor: pointer;
+}
+
.header-brand-img {
height: 32px;
}
diff --git a/client/src/components/Header/Menu.js b/client/src/components/Header/Menu.js
index ef465378..2800d768 100644
--- a/client/src/components/Header/Menu.js
+++ b/client/src/components/Header/Menu.js
@@ -4,7 +4,6 @@ import PropTypes from 'prop-types';
import enhanceWithClickOutside from 'react-click-outside';
import classnames from 'classnames';
import { Trans, withNamespaces } from 'react-i18next';
-import { REPOSITORY } from '../../helpers/constants';
class Menu extends Component {
handleClickOutside = () => {
@@ -56,10 +55,10 @@ class Menu extends Component {
-
+
- faq
-
+ setup_guide
+
diff --git a/client/src/components/Header/Version.js b/client/src/components/Header/Version.js
index 0faedbcc..be2158e9 100644
--- a/client/src/components/Header/Version.js
+++ b/client/src/components/Header/Version.js
@@ -2,24 +2,35 @@ import React from 'react';
import PropTypes from 'prop-types';
import { Trans, withNamespaces } from 'react-i18next';
+import { getDnsAddress } from '../../helpers/helpers';
+
function Version(props) {
- const { dnsVersion, dnsAddress, dnsPort } = props;
+ const { dnsVersion, dnsAddresses, dnsPort } = props;
return (
version : {dnsVersion}
-
-
address :
{dnsAddress}:{dnsPort}
+
+
+ dns_addresses
+
+
+
+ {dnsAddresses
+ .map(ip =>
{getDnsAddress(ip, dnsPort)} )
+ }
+
+
);
}
Version.propTypes = {
- dnsVersion: PropTypes.string,
- dnsAddress: PropTypes.string,
- dnsPort: PropTypes.number,
+ dnsVersion: PropTypes.string.isRequired,
+ dnsAddresses: PropTypes.array.isRequired,
+ dnsPort: PropTypes.number.isRequired,
};
export default withNamespaces()(Version);
diff --git a/client/src/components/Header/index.js b/client/src/components/Header/index.js
index ecc1a2af..e2d47fe6 100644
--- a/client/src/components/Header/index.js
+++ b/client/src/components/Header/index.js
@@ -56,11 +56,13 @@ class Header extends Component {
toggleMenuOpen={this.toggleMenuOpen}
closeMenu={this.closeMenu}
/>
-
-
-
+ {!dashboard.processing &&
+
+
+
+ }
diff --git a/client/src/components/SetupGuide/Guide.css b/client/src/components/SetupGuide/Guide.css
new file mode 100644
index 00000000..821f1798
--- /dev/null
+++ b/client/src/components/SetupGuide/Guide.css
@@ -0,0 +1,15 @@
+.guide {
+ max-width: 768px;
+ margin: 0 auto;
+}
+
+.guide__title {
+ margin-bottom: 10px;
+ font-size: 17px;
+ font-weight: 700;
+}
+
+.guide__desc {
+ margin-bottom: 20px;
+ font-size: 15px;
+}
diff --git a/client/src/components/SetupGuide/index.js b/client/src/components/SetupGuide/index.js
new file mode 100644
index 00000000..bea2bbb1
--- /dev/null
+++ b/client/src/components/SetupGuide/index.js
@@ -0,0 +1,46 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { Trans, withNamespaces } from 'react-i18next';
+
+import { getDnsAddress } from '../../helpers/helpers';
+
+import Guide from '../ui/Guide';
+import Card from '../ui/Card';
+import PageTitle from '../ui/PageTitle';
+import './Guide.css';
+
+const SetupGuide = ({
+ t,
+ dashboard: {
+ dnsAddresses,
+ dnsPort,
+ },
+}) => (
+
+
+
+
+ install_devices_title
+
+
+
install_devices_desc
+
+ install_devices_address :
+
+
+ {dnsAddresses
+ .map(ip =>
{getDnsAddress(ip, dnsPort)} )
+ }
+
+
+
+
+
+);
+
+SetupGuide.propTypes = {
+ dashboard: PropTypes.object.isRequired,
+ t: PropTypes.func.isRequired,
+};
+
+export default withNamespaces()(SetupGuide);
diff --git a/client/src/components/ui/Guide.js b/client/src/components/ui/Guide.js
new file mode 100644
index 00000000..9e89f7ec
--- /dev/null
+++ b/client/src/components/ui/Guide.js
@@ -0,0 +1,83 @@
+import React from 'react';
+import { Trans, withNamespaces } from 'react-i18next';
+
+import Tabs from '../ui/Tabs';
+import Icons from '../ui/Icons';
+
+const Guide = () => (
+
+
+
+
+
+ install_devices_router
+
+
+
install_devices_router_desc
+
+ install_devices_router_list_1
+ install_devices_router_list_2
+ install_devices_router_list_3
+
+
+
+
+
+ Windows
+
+
+
+ install_devices_windows_list_1
+ install_devices_windows_list_2
+ install_devices_windows_list_3
+ install_devices_windows_list_4
+ install_devices_windows_list_5
+ install_devices_windows_list_6
+
+
+
+
+
+ macOS
+
+
+
+ install_devices_macos_list_1
+ install_devices_macos_list_2
+ install_devices_macos_list_3
+ install_devices_macos_list_4
+
+
+
+
+
+ Android
+
+
+
+ install_devices_android_list_1
+ install_devices_android_list_2
+ install_devices_android_list_3
+ install_devices_android_list_4
+ install_devices_android_list_5
+
+
+
+
+
+ iOS
+
+
+
+ install_devices_ios_list_1
+ install_devices_ios_list_2
+ install_devices_ios_list_3
+ install_devices_ios_list_4
+
+
+
+
+
+);
+
+export default withNamespaces()(Guide);
diff --git a/client/src/components/ui/Popover.css b/client/src/components/ui/Popover.css
index dc83e4cb..f7e23836 100644
--- a/client/src/components/ui/Popover.css
+++ b/client/src/components/ui/Popover.css
@@ -22,6 +22,16 @@
height: 24px;
}
+.popover__trigger--address {
+ top: 0;
+ margin: 0;
+ line-height: 1.2;
+}
+
+.popover__trigger--address:after {
+ display: none;
+}
+
.popover__body {
content: "";
display: flex;
@@ -57,6 +67,38 @@
border-top: 6px solid #585965;
}
+.popover__body--address {
+ top: calc(100% + 10px);
+ right: 0;
+ left: initial;
+ bottom: initial;
+ z-index: 1;
+ min-width: 100px;
+ padding: 12px 18px;
+ font-weight: 700;
+ text-align: left;
+ white-space: nowrap;
+ transform: none;
+ cursor: default;
+}
+
+.popover__body--address:after {
+ top: -11px;
+ left: initial;
+ right: 40px;
+ border-top: 6px solid transparent;
+ border-bottom: 6px solid #585965;
+}
+
+.popover__body--address:before {
+ content: "";
+ position: absolute;
+ top: -7px;
+ left: 0;
+ width: 100%;
+ height: 10px;
+}
+
.popover__trigger:hover + .popover__body,
.popover__body:hover {
visibility: visible;
@@ -73,6 +115,10 @@
stroke: #66b574;
}
+.popover__list--bold {
+ font-weight: 700;
+}
+
.popover__list-title {
margin-bottom: 3px;
}
diff --git a/client/src/containers/SetupGuide.js b/client/src/containers/SetupGuide.js
new file mode 100644
index 00000000..1e7ecd12
--- /dev/null
+++ b/client/src/containers/SetupGuide.js
@@ -0,0 +1,14 @@
+import { connect } from 'react-redux';
+import * as actionCreators from '../actions';
+import SetupGuide from '../components/SetupGuide';
+
+const mapStateToProps = (state) => {
+ const { dashboard } = state;
+ const props = { dashboard };
+ return props;
+};
+
+export default connect(
+ mapStateToProps,
+ actionCreators,
+)(SetupGuide);
diff --git a/client/src/install/Setup/Devices.js b/client/src/install/Setup/Devices.js
index 4a5f7c13..f3755b3d 100644
--- a/client/src/install/Setup/Devices.js
+++ b/client/src/install/Setup/Devices.js
@@ -5,8 +5,7 @@ import { reduxForm, formValueSelector } from 'redux-form';
import { Trans, withNamespaces } from 'react-i18next';
import flow from 'lodash/flow';
-import Tabs from '../../components/ui/Tabs';
-import Icons from '../../components/ui/Icons';
+import Guide from '../../components/ui/Guide';
import Controls from './Controls';
import AddressList from './AddressList';
@@ -30,77 +29,7 @@ let Devices = props => (
/>
-
-
-
-
- install_devices_router
-
-
-
install_devices_router_desc
-
- install_devices_router_list_1
- install_devices_router_list_2
- install_devices_router_list_3
-
-
-
-
-
- Windows
-
-
-
- install_devices_windows_list_1
- install_devices_windows_list_2
- install_devices_windows_list_3
- install_devices_windows_list_4
- install_devices_windows_list_5
- install_devices_windows_list_6
-
-
-
-
-
- macOS
-
-
-
- install_devices_macos_list_1
- install_devices_macos_list_2
- install_devices_macos_list_3
- install_devices_macos_list_4
-
-
-
-
-
- Android
-
-
-
- install_devices_android_list_1
- install_devices_android_list_2
- install_devices_android_list_3
- install_devices_android_list_4
- install_devices_android_list_5
-
-
-
-
-
- iOS
-
-
-
- install_devices_ios_list_1
- install_devices_ios_list_2
- install_devices_ios_list_3
- install_devices_ios_list_4
-
-
-
-
+
diff --git a/client/src/reducers/index.js b/client/src/reducers/index.js
index 90ace4d6..a6daef82 100644
--- a/client/src/reducers/index.js
+++ b/client/src/reducers/index.js
@@ -48,7 +48,7 @@ const dashboard = handleActions({
version,
running,
dns_port: dnsPort,
- dns_address: dnsAddress,
+ dns_addresses: dnsAddresses,
querylog_enabled: queryLogEnabled,
upstream_dns: upstreamDns,
bootstrap_dns: bootstrapDns,
@@ -63,7 +63,7 @@ const dashboard = handleActions({
processing: false,
dnsVersion: version,
dnsPort,
- dnsAddress,
+ dnsAddresses,
queryLogEnabled,
upstreamDns: upstreamDns.join('\n'),
bootstrapDns: bootstrapDns.join('\n'),
@@ -181,6 +181,9 @@ const dashboard = handleActions({
protectionEnabled: false,
processingProtection: false,
httpPort: 80,
+ dnsPort: 53,
+ dnsAddresses: [],
+ dnsVersion: '',
});
const queryLogs = handleActions({