diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json index 550d887e..340c5bcb 100644 --- a/client/src/__locales/en.json +++ b/client/src/__locales/en.json @@ -1,6 +1,7 @@ { "client_settings": "Client settings", "example_upstream_reserved": "You can specify DNS upstream <0>for the specific domain(s)", + "example_upstream_comment": "You can specify the comment", "upstream_parallel": "Use parallel requests to speed up resolving by simultaneously querying all upstream servers", "parallel_requests": "Parallel requests", "load_balancing": "Load-balancing", @@ -581,4 +582,4 @@ "port_53_faq_link": "Port 53 is often occupied by \"DNSStubListener\" or \"systemd-resolved\" services. Please read <0>this instruction on how to resolve this.", "adg_will_drop_dns_queries": "AdGuard Home will be dropping all DNS queries from this client.", "experimental": "Experimental" -} \ No newline at end of file +} diff --git a/client/src/actions/index.js b/client/src/actions/index.js index d39975ea..efd432fd 100644 --- a/client/src/actions/index.js +++ b/client/src/actions/index.js @@ -5,9 +5,15 @@ import axios from 'axios'; import endsWith from 'lodash/endsWith'; import escapeRegExp from 'lodash/escapeRegExp'; import React from 'react'; -import { splitByNewLine, sortClients } from '../helpers/helpers'; +import { compose } from 'redux'; +import { splitByNewLine, sortClients, filterOutComments } from '../helpers/helpers'; import { - BLOCK_ACTIONS, CHECK_TIMEOUT, STATUS_RESPONSE, SETTINGS_NAMES, FORM_NAME, GETTING_STARTED_LINK, + BLOCK_ACTIONS, + CHECK_TIMEOUT, + STATUS_RESPONSE, + SETTINGS_NAMES, + FORM_NAME, + GETTING_STARTED_LINK, } from '../helpers/constants'; import { areEqualVersions } from '../helpers/version'; import { getTlsStatus } from './encryption'; @@ -289,14 +295,21 @@ export const testUpstreamRequest = createAction('TEST_UPSTREAM_REQUEST'); export const testUpstreamFailure = createAction('TEST_UPSTREAM_FAILURE'); export const testUpstreamSuccess = createAction('TEST_UPSTREAM_SUCCESS'); -export const testUpstream = (config) => async (dispatch) => { +export const testUpstream = ( + { bootstrap_dns, upstream_dns }, upstream_dns_file, +) => async (dispatch) => { dispatch(testUpstreamRequest()); try { - const values = { ...config }; - values.bootstrap_dns = splitByNewLine(values.bootstrap_dns); - values.upstream_dns = splitByNewLine(values.upstream_dns); + const removeComments = compose(filterOutComments, splitByNewLine); - const upstreamResponse = await apiClient.testUpstream(values); + const config = { + bootstrap_dns: splitByNewLine(bootstrap_dns), + ...(upstream_dns_file ? null : { + upstream_dns: removeComments(upstream_dns), + }), + }; + + const upstreamResponse = await apiClient.testUpstream(config); const testMessages = Object.keys(upstreamResponse) .map((key) => { const message = upstreamResponse[key]; @@ -317,6 +330,12 @@ export const testUpstream = (config) => async (dispatch) => { } }; +export const testUpstreamWithFormValues = () => async (dispatch, getState) => { + const { upstream_dns_file } = getState().dnsConfig; + const { bootstrap_dns, upstream_dns } = getState().form[FORM_NAME.UPSTREAM].values; + return dispatch(testUpstream({ bootstrap_dns, upstream_dns }, upstream_dns_file)); +}; + export const changeLanguageRequest = createAction('CHANGE_LANGUAGE_REQUEST'); export const changeLanguageFailure = createAction('CHANGE_LANGUAGE_FAILURE'); export const changeLanguageSuccess = createAction('CHANGE_LANGUAGE_SUCCESS'); diff --git a/client/src/components/Filters/CustomRules.js b/client/src/components/Filters/CustomRules.js index 6a423026..723add5c 100644 --- a/client/src/components/Filters/CustomRules.js +++ b/client/src/components/Filters/CustomRules.js @@ -1,13 +1,18 @@ -import React, { Component, Fragment } from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { Trans, withTranslation } from 'react-i18next'; - +import classnames from 'classnames'; import Card from '../ui/Card'; import PageTitle from '../ui/PageTitle'; import Examples from './Examples'; import Check from './Check'; +import { getTextareaCommentsHighlight, syncScroll } from '../../helpers/highlightTextareaComments'; +import { COMMENT_LINE_DEFAULT_TOKEN, isFirefox } from '../../helpers/constants'; +import '../ui/texareaCommentsHighlight.css'; class CustomRules extends Component { + ref = React.createRef(); + componentDidMount() { this.props.getFilteringStatus(); } @@ -34,6 +39,8 @@ class CustomRules extends Component { this.props.checkHost(values); }; + onScroll = (e) => syncScroll(e, this.ref) + render() { const { t, @@ -47,17 +54,31 @@ class CustomRules extends Component { } = this.props; return ( - + <>
+