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 here 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

    +
      +
    1. install_devices_router_list_1
    2. +
    3. install_devices_router_list_2
    4. +
    5. install_devices_router_list_3
    6. +
    +
    +
    +
    +
    + Windows +
    +
    +
      +
    1. install_devices_windows_list_1
    2. +
    3. install_devices_windows_list_2
    4. +
    5. install_devices_windows_list_3
    6. +
    7. install_devices_windows_list_4
    8. +
    9. install_devices_windows_list_5
    10. +
    11. install_devices_windows_list_6
    12. +
    +
    +
    +
    +
    + macOS +
    +
    +
      +
    1. install_devices_macos_list_1
    2. +
    3. install_devices_macos_list_2
    4. +
    5. install_devices_macos_list_3
    6. +
    7. install_devices_macos_list_4
    8. +
    +
    +
    +
    +
    + Android +
    +
    +
      +
    1. install_devices_android_list_1
    2. +
    3. install_devices_android_list_2
    4. +
    5. install_devices_android_list_3
    6. +
    7. install_devices_android_list_4
    8. +
    9. install_devices_android_list_5
    10. +
    +
    +
    +
    +
    + iOS +
    +
    +
      +
    1. install_devices_ios_list_1
    2. +
    3. install_devices_ios_list_2
    4. +
    5. install_devices_ios_list_3
    6. +
    7. install_devices_ios_list_4
    8. +
    +
    +
    +
    +
    +); + +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

    -
      -
    1. install_devices_router_list_1
    2. -
    3. install_devices_router_list_2
    4. -
    5. install_devices_router_list_3
    6. -
    -
    -
    -
    -
    - Windows -
    -
    -
      -
    1. install_devices_windows_list_1
    2. -
    3. install_devices_windows_list_2
    4. -
    5. install_devices_windows_list_3
    6. -
    7. install_devices_windows_list_4
    8. -
    9. install_devices_windows_list_5
    10. -
    11. install_devices_windows_list_6
    12. -
    -
    -
    -
    -
    - macOS -
    -
    -
      -
    1. install_devices_macos_list_1
    2. -
    3. install_devices_macos_list_2
    4. -
    5. install_devices_macos_list_3
    6. -
    7. install_devices_macos_list_4
    8. -
    -
    -
    -
    -
    - Android -
    -
    -
      -
    1. install_devices_android_list_1
    2. -
    3. install_devices_android_list_2
    4. -
    5. install_devices_android_list_3
    6. -
    7. install_devices_android_list_4
    8. -
    9. install_devices_android_list_5
    10. -
    -
    -
    -
    -
    - iOS -
    -
    -
      -
    1. install_devices_ios_list_1
    2. -
    3. install_devices_ios_list_2
    4. -
    5. install_devices_ios_list_3
    6. -
    7. install_devices_ios_list_4
    8. -
    -
    -
    -
    + 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({