+ client: Allow Fastest IP address
and Parallel requests
to toggle each other: Merge pull request #619 in DNS/adguard-home from feature/1678 to master
Close #1678 Squashed commit of the following: commit 9251ed0f1b58426104d1b9bdaa4b7af5f92be83e Author: ArtemBaskal <a.baskal@adguard.com> Date: Thu May 21 18:25:18 2020 +0300 + client: Allow `Fastest IP address` and `Parallel requests` to toggle each other
This commit is contained in:
parent
2f5073b720
commit
383507bc0c
@ -456,7 +456,7 @@
|
||||
"disable_ipv6": "Disable IPv6",
|
||||
"disable_ipv6_desc": "If this feature is enabled, all DNS queries for IPv6 addresses (type AAAA) will be dropped.",
|
||||
"fastest_addr": "Fastest IP address",
|
||||
"fastest_addr_desc": "Query all DNS servers and return the fastest IP address among all responses",
|
||||
"fastest_addr_desc": "Query all DNS servers and return the fastest IP address among all responses. This will slow down the DNS queries as we have to wait for responses from all DNS servers, but improve the overall connectivity.",
|
||||
"autofix_warning_text": "If you click \"Fix\", AdGuard Home will configure your system to use AdGuard Home DNS server.",
|
||||
"autofix_warning_list": "It will perform these tasks: <0>Deactivate system DNSStubListener</0> <0>Set DNS server address to 127.0.0.1</0> <0>Replace symbolic link target of /etc/resolv.conf with /run/systemd/resolve/resolv.conf</0> <0>Stop DNSStubListener (reload systemd-resolved service)</0>",
|
||||
"autofix_warning_result": "As a result all DNS requests from your system will be processed by AdGuard Home by default.",
|
||||
@ -490,4 +490,4 @@
|
||||
"list_updated_plural": "{{count}} lists updated",
|
||||
"dnssec_enable": "Enable DNSSEC",
|
||||
"dnssec_enable_desc": "Set DNSSEC flag in the outcoming DNS queries and check the result (DNSSEC-enabled resolver is required)"
|
||||
}
|
||||
}
|
||||
|
@ -19,18 +19,18 @@ const Form = (props) => {
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="modal-body">
|
||||
<div className="form__group">
|
||||
<Field
|
||||
id="name"
|
||||
name="name"
|
||||
type="text"
|
||||
component={renderInputField}
|
||||
className="form-control"
|
||||
placeholder={t('enter_name_hint')}
|
||||
validate={[required]}
|
||||
normalizeOnBlur={(data) => data.trim()}
|
||||
/>
|
||||
</div>
|
||||
<div className="form__group">
|
||||
<Field
|
||||
id="name"
|
||||
name="name"
|
||||
type="text"
|
||||
component={renderInputField}
|
||||
className="form-control"
|
||||
placeholder={t('enter_name_hint')}
|
||||
validate={[required]}
|
||||
normalizeOnBlur={(data) => data.trim()}
|
||||
/>
|
||||
</div>
|
||||
<div className="form__group">
|
||||
<Field
|
||||
id="url"
|
||||
|
@ -5,11 +5,13 @@ import { Field, reduxForm, formValueSelector } from 'redux-form';
|
||||
import { Trans, withTranslation } from 'react-i18next';
|
||||
import flow from 'lodash/flow';
|
||||
import classnames from 'classnames';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
import Examples from './Examples';
|
||||
import { renderSelectField } from '../../../../helpers/form';
|
||||
import { renderRadioField } from '../../../../helpers/form';
|
||||
import { DNS_REQUEST_OPTIONS } from '../../../../helpers/constants';
|
||||
|
||||
const getInputFields = (parallel_requests_selected, fastest_addr_selected) => [{
|
||||
const getInputFields = () => [{
|
||||
// eslint-disable-next-line react/display-name
|
||||
getTitle: () => <label className="form__label" htmlFor="upstream_dns">
|
||||
<Trans>upstream_dns</Trans>
|
||||
@ -21,20 +23,20 @@ const getInputFields = (parallel_requests_selected, fastest_addr_selected) => [{
|
||||
placeholder: 'upstream_dns',
|
||||
},
|
||||
{
|
||||
name: 'parallel_requests',
|
||||
placeholder: 'parallel_requests',
|
||||
component: renderSelectField,
|
||||
type: 'checkbox',
|
||||
name: 'dnsRequestOption',
|
||||
type: 'radio',
|
||||
value: DNS_REQUEST_OPTIONS.PARALLEL_REQUESTS,
|
||||
component: renderRadioField,
|
||||
subtitle: 'upstream_parallel',
|
||||
disabled: fastest_addr_selected,
|
||||
placeholder: 'parallel_requests',
|
||||
},
|
||||
{
|
||||
name: 'fastest_addr',
|
||||
placeholder: 'fastest_addr',
|
||||
component: renderSelectField,
|
||||
type: 'checkbox',
|
||||
name: 'dnsRequestOption',
|
||||
type: 'radio',
|
||||
value: DNS_REQUEST_OPTIONS.FASTEST_ADDR,
|
||||
component: renderRadioField,
|
||||
subtitle: 'fastest_addr_desc',
|
||||
disabled: parallel_requests_selected,
|
||||
placeholder: 'fastest_addr',
|
||||
}];
|
||||
|
||||
let Form = (props) => {
|
||||
@ -46,8 +48,6 @@ let Form = (props) => {
|
||||
invalid,
|
||||
processingSetConfig,
|
||||
processingTestUpstream,
|
||||
fastest_addr,
|
||||
parallel_requests,
|
||||
upstream_dns,
|
||||
bootstrap_dns,
|
||||
} = props;
|
||||
@ -57,78 +57,77 @@ let Form = (props) => {
|
||||
'btn btn-primary btn-standard mr-2 btn-loading': processingTestUpstream,
|
||||
});
|
||||
|
||||
const INPUT_FIELDS = getInputFields(parallel_requests, fastest_addr);
|
||||
const INPUT_FIELDS = getInputFields();
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="row">
|
||||
{INPUT_FIELDS.map(({
|
||||
name, component, type, className, placeholder, getTitle, subtitle, disabled,
|
||||
}) => <div className="col-12 mb-4" key={name}>
|
||||
{typeof getTitle === 'function' && getTitle()}
|
||||
<Field
|
||||
id={name}
|
||||
name={name}
|
||||
component={component}
|
||||
type={type}
|
||||
className={className}
|
||||
placeholder={t(placeholder)}
|
||||
subtitle={t(subtitle)}
|
||||
disabled={processingSetConfig || processingTestUpstream || disabled}
|
||||
/>
|
||||
</div>)}
|
||||
<div className="col-12">
|
||||
<Examples />
|
||||
<hr />
|
||||
</div>
|
||||
<div className="col-12 mb-4">
|
||||
<label
|
||||
className="form__label form__label--with-desc"
|
||||
htmlFor="bootstrap_dns"
|
||||
>
|
||||
<Trans>bootstrap_dns</Trans>
|
||||
</label>
|
||||
<div className="form__desc form__desc--top">
|
||||
<Trans>bootstrap_dns_desc</Trans>
|
||||
</div>
|
||||
<Field
|
||||
id="bootstrap_dns"
|
||||
name="bootstrap_dns"
|
||||
component="textarea"
|
||||
type="text"
|
||||
className="form-control form-control--textarea form-control--textarea-small font-monospace"
|
||||
placeholder={t('bootstrap_dns')}
|
||||
disabled={processingSetConfig}
|
||||
/>
|
||||
</div>
|
||||
return <form onSubmit={handleSubmit}>
|
||||
<div className="row">
|
||||
{INPUT_FIELDS.map(({
|
||||
name, component, type, className, placeholder, getTitle, subtitle, disabled, value,
|
||||
}) => <div className="col-12 mb-4" key={nanoid()}>
|
||||
{typeof getTitle === 'function' && getTitle()}
|
||||
<Field
|
||||
id={name}
|
||||
value={value}
|
||||
name={name}
|
||||
component={component}
|
||||
type={type}
|
||||
className={className}
|
||||
placeholder={t(placeholder)}
|
||||
subtitle={t(subtitle)}
|
||||
disabled={processingSetConfig || processingTestUpstream || disabled}
|
||||
/>
|
||||
</div>)}
|
||||
<div className="col-12">
|
||||
<Examples />
|
||||
<hr />
|
||||
</div>
|
||||
<div className="card-actions">
|
||||
<div className="btn-list">
|
||||
<button
|
||||
type="button"
|
||||
className={testButtonClass}
|
||||
onClick={() => testUpstream({
|
||||
upstream_dns,
|
||||
bootstrap_dns,
|
||||
})
|
||||
}
|
||||
disabled={!upstream_dns || processingTestUpstream}
|
||||
>
|
||||
<Trans>test_upstream_btn</Trans>
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-success btn-standard"
|
||||
disabled={
|
||||
submitting || invalid || processingSetConfig || processingTestUpstream
|
||||
}
|
||||
>
|
||||
<Trans>apply_btn</Trans>
|
||||
</button>
|
||||
<div className="col-12 mb-4">
|
||||
<label
|
||||
className="form__label form__label--with-desc"
|
||||
htmlFor="bootstrap_dns"
|
||||
>
|
||||
<Trans>bootstrap_dns</Trans>
|
||||
</label>
|
||||
<div className="form__desc form__desc--top">
|
||||
<Trans>bootstrap_dns_desc</Trans>
|
||||
</div>
|
||||
<Field
|
||||
id="bootstrap_dns"
|
||||
name="bootstrap_dns"
|
||||
component="textarea"
|
||||
type="text"
|
||||
className="form-control form-control--textarea form-control--textarea-small font-monospace"
|
||||
placeholder={t('bootstrap_dns')}
|
||||
disabled={processingSetConfig}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
</div>
|
||||
<div className="card-actions">
|
||||
<div className="btn-list">
|
||||
<button
|
||||
type="button"
|
||||
className={testButtonClass}
|
||||
onClick={() => testUpstream({
|
||||
upstream_dns,
|
||||
bootstrap_dns,
|
||||
})
|
||||
}
|
||||
disabled={!upstream_dns || processingTestUpstream}
|
||||
>
|
||||
<Trans>test_upstream_btn</Trans>
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-success btn-standard"
|
||||
disabled={
|
||||
submitting || invalid || processingSetConfig || processingTestUpstream
|
||||
}
|
||||
>
|
||||
<Trans>apply_btn</Trans>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>;
|
||||
};
|
||||
|
||||
Form.propTypes = {
|
||||
@ -139,8 +138,6 @@ Form.propTypes = {
|
||||
initialValues: PropTypes.object,
|
||||
upstream_dns: PropTypes.string,
|
||||
bootstrap_dns: PropTypes.string,
|
||||
fastest_addr: PropTypes.bool,
|
||||
parallel_requests: PropTypes.bool,
|
||||
processingTestUpstream: PropTypes.bool,
|
||||
processingSetConfig: PropTypes.bool,
|
||||
t: PropTypes.func,
|
||||
@ -151,14 +148,10 @@ const selector = formValueSelector('upstreamForm');
|
||||
Form = connect((state) => {
|
||||
const upstream_dns = selector(state, 'upstream_dns');
|
||||
const bootstrap_dns = selector(state, 'bootstrap_dns');
|
||||
const fastest_addr = selector(state, 'fastest_addr');
|
||||
const parallel_requests = selector(state, 'parallel_requests');
|
||||
|
||||
return {
|
||||
upstream_dns,
|
||||
bootstrap_dns,
|
||||
fastest_addr,
|
||||
parallel_requests,
|
||||
};
|
||||
})(Form);
|
||||
|
||||
|
@ -1,13 +1,27 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import cn from 'classnames';
|
||||
|
||||
import Form from './Form';
|
||||
import Card from '../../../ui/Card';
|
||||
import { DNS_REQUEST_OPTIONS } from '../../../../helpers/constants';
|
||||
|
||||
|
||||
class Upstream extends Component {
|
||||
handleSubmit = (values) => {
|
||||
this.props.setDnsConfig(values);
|
||||
handleSubmit = ({ bootstrap_dns, upstream_dns, dnsRequestOption }) => {
|
||||
const disabledOption = dnsRequestOption === DNS_REQUEST_OPTIONS.PARALLEL_REQUESTS
|
||||
? DNS_REQUEST_OPTIONS.FASTEST_ADDR
|
||||
: DNS_REQUEST_OPTIONS.PARALLEL_REQUESTS;
|
||||
|
||||
const formattedValues = {
|
||||
bootstrap_dns,
|
||||
upstream_dns,
|
||||
[dnsRequestOption]: true,
|
||||
[disabledOption]: false,
|
||||
};
|
||||
|
||||
this.props.setDnsConfig(formattedValues);
|
||||
};
|
||||
|
||||
handleTest = (values) => {
|
||||
@ -27,6 +41,11 @@ class Upstream extends Component {
|
||||
},
|
||||
} = this.props;
|
||||
|
||||
const dnsRequestOption = cn({
|
||||
parallel_requests,
|
||||
fastest_addr,
|
||||
});
|
||||
|
||||
return (
|
||||
<Card
|
||||
title={t('upstream_dns')}
|
||||
@ -39,8 +58,7 @@ class Upstream extends Component {
|
||||
initialValues={{
|
||||
upstream_dns,
|
||||
bootstrap_dns,
|
||||
fastest_addr,
|
||||
parallel_requests,
|
||||
dnsRequestOption,
|
||||
}}
|
||||
testUpstream={this.handleTest}
|
||||
onSubmit={this.handleSubmit}
|
||||
|
@ -374,3 +374,8 @@ export const ACTION = {
|
||||
block: 'block',
|
||||
unblock: 'unblock',
|
||||
};
|
||||
|
||||
export const DNS_REQUEST_OPTIONS = {
|
||||
PARALLEL_REQUESTS: 'parallel_requests',
|
||||
FASTEST_ADDR: 'fastest_addr',
|
||||
};
|
||||
|
@ -119,11 +119,19 @@ renderGroupField.propTypes = {
|
||||
};
|
||||
|
||||
export const renderRadioField = ({
|
||||
input, placeholder, disabled, meta: { touched, error },
|
||||
input,
|
||||
placeholder,
|
||||
subtitle,
|
||||
disabled,
|
||||
meta: { touched, error },
|
||||
}) => <Fragment>
|
||||
<label className="custom-control custom-radio custom-control-inline">
|
||||
<label className="custom-control custom-radio">
|
||||
<input {...input} type="radio" className="custom-control-input" disabled={disabled} />
|
||||
<span className="custom-control-label">{placeholder}</span>
|
||||
{subtitle && <span
|
||||
className="checkbox__label-subtitle"
|
||||
dangerouslySetInnerHTML={{ __html: subtitle }}
|
||||
/>}
|
||||
</label>
|
||||
{!disabled
|
||||
&& touched
|
||||
@ -133,6 +141,7 @@ export const renderRadioField = ({
|
||||
renderRadioField.propTypes = {
|
||||
input: PropTypes.object.isRequired,
|
||||
placeholder: PropTypes.string,
|
||||
subtitle: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
meta: PropTypes.shape({
|
||||
touched: PropTypes.bool,
|
||||
@ -155,12 +164,10 @@ export const renderSelectField = ({
|
||||
<span className="checkbox__label">
|
||||
<span className="checkbox__label-text checkbox__label-text--long">
|
||||
<span className="checkbox__label-title">{placeholder}</span>
|
||||
{subtitle && (
|
||||
<span
|
||||
className="checkbox__label-subtitle"
|
||||
dangerouslySetInnerHTML={{ __html: subtitle }}
|
||||
/>
|
||||
)}
|
||||
{subtitle && <span
|
||||
className="checkbox__label-subtitle"
|
||||
dangerouslySetInnerHTML={{ __html: subtitle }}
|
||||
/>}
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
|
Loading…
Reference in New Issue
Block a user