From d9c57cdd9a884422e3c62907bd57d50949e5030a Mon Sep 17 00:00:00 2001 From: Ainar Garipov Date: Wed, 12 Apr 2023 14:48:42 +0300 Subject: [PATCH] all: sync with master; upd chlog --- AGHTechDoc.md | 1 + CHANGELOG.md | 158 +++- client/dev.eslintrc | 2 +- client/src/__locales/cs.json | 28 +- client/src/__locales/da.json | 28 +- client/src/__locales/de.json | 28 +- client/src/__locales/en.json | 28 +- client/src/__locales/es.json | 28 +- client/src/__locales/fi.json | 44 +- client/src/__locales/fr.json | 28 +- client/src/__locales/hr.json | 28 +- client/src/__locales/it.json | 28 +- client/src/__locales/ja.json | 28 +- client/src/__locales/ko.json | 28 +- client/src/__locales/nl.json | 28 +- client/src/__locales/pt-br.json | 28 +- client/src/__locales/pt-pt.json | 28 +- client/src/__locales/ru.json | 28 +- client/src/__locales/sk.json | 28 +- client/src/__locales/sl.json | 28 +- client/src/__locales/sv.json | 12 +- client/src/__locales/tr.json | 28 +- client/src/__locales/zh-cn.json | 28 +- client/src/__locales/zh-tw.json | 28 +- client/src/actions/encryption.js | 3 + client/src/actions/index.js | 81 +- client/src/actions/queryLogs.js | 2 +- client/src/actions/stats.js | 2 +- client/src/api/Api.js | 65 +- client/src/components/App/index.js | 5 +- client/src/components/Dashboard/Dashboard.css | 15 +- client/src/components/Dashboard/index.js | 114 ++- client/src/components/Filters/DnsBlocklist.js | 10 +- .../src/components/ProtectionTimer/index.js | 52 ++ .../Clients/ClientsTable/ClientsTable.js | 6 + .../src/components/Settings/Clients/Form.js | 33 +- client/src/components/Settings/Dhcp/Leases.js | 35 +- .../Settings/Dhcp/StaticLeases/Form.js | 5 +- .../Settings/Dhcp/StaticLeases/Modal.js | 11 +- client/src/components/Settings/Dhcp/index.js | 6 +- .../components/Settings/Dns/Config/Form.js | 41 +- .../components/Settings/Dns/Config/index.js | 4 + .../components/Settings/LogsConfig/Form.js | 36 +- .../components/Settings/LogsConfig/index.js | 10 +- client/src/components/Settings/Settings.css | 8 + .../components/Settings/StatsConfig/Form.js | 48 +- .../components/Settings/StatsConfig/index.js | 15 +- client/src/components/Settings/index.js | 46 +- client/src/components/Toasts/Toast.css | 5 + client/src/components/ui/Checkbox.js | 4 +- client/src/components/ui/Dropdown.css | 56 ++ client/src/components/ui/Footer.css | 35 + client/src/components/ui/Footer.js | 102 ++- client/src/components/ui/Guide/Guide.js | 2 - client/src/components/ui/Icons.js | 23 +- client/src/components/ui/Line.js | 3 +- client/src/components/ui/Tabler.css | 12 + client/src/helpers/constants.js | 20 +- client/src/helpers/filters/filters.js | 4 +- client/src/helpers/helpers.js | 18 +- client/src/helpers/trackers/trackers.json | 101 ++- client/src/install/Setup/index.js | 2 + client/src/login/Login/index.js | 2 + client/src/reducers/dashboard.js | 14 +- client/src/reducers/dhcp.js | 4 +- client/src/reducers/queryLogs.js | 4 +- client/src/reducers/settings.js | 4 +- client/src/reducers/stats.js | 7 +- {scripts/make => docker}/Dockerfile | 24 +- docker/dns-bind.awk | 22 + docker/healthcheck.sh | 89 ++ docker/web-bind.awk | 13 + go.mod | 33 +- go.sum | 62 +- internal/aghhttp/aghhttp.go | 5 +- internal/aghhttp/header.go | 18 +- internal/aghnet/hostgen.go | 85 +- internal/aghnet/hostgen_test.go | 35 +- internal/aghnet/hostscontainer.go | 55 +- internal/aghnet/testdata/etc_hosts | 2 +- internal/aghnet/testdata/ifaces | 2 +- internal/aghnet/testdata/include-subsources | 2 +- internal/aghnet/testdata/proc_net_arp | 2 +- internal/aghos/endian_big.go | 10 - internal/aghos/endian_little.go | 10 - internal/dhcpd/conn_unix.go | 10 +- internal/dhcpd/conn_unix_test.go | 8 +- internal/dhcpd/db.go | 17 +- internal/dhcpd/dhcpd.go | 26 +- internal/dhcpd/dhcpd_unix_test.go | 8 +- internal/dhcpd/http_unix.go | 125 ++- internal/dhcpd/http_unix_test.go | 160 ++++ internal/dhcpd/iprange.go | 4 +- internal/dhcpd/v4_unix.go | 103 ++- internal/dhcpd/v4_unix_test.go | 210 ++++- internal/dhcpd/v6_unix.go | 45 +- internal/dhcpd/v6_unix_test.go | 95 +- internal/dnsforward/config.go | 75 +- internal/dnsforward/dns.go | 144 ++- internal/dnsforward/dns64.go | 2 - internal/dnsforward/dns_test.go | 126 +++ internal/dnsforward/dnsforward.go | 7 + internal/dnsforward/dnsforward_test.go | 27 +- internal/dnsforward/http.go | 234 +++-- internal/dnsforward/http_test.go | 33 +- internal/dnsforward/stats.go | 20 +- internal/dnsforward/stats_test.go | 4 +- .../TestDNSForwardHTTP_handleGetConfig.json | 15 +- .../TestDNSForwardHTTP_handleSetConfig.json | 163 +++- internal/filtering/filter.go | 84 +- internal/filtering/filtering.go | 31 +- internal/filtering/filtering_test.go | 187 +--- internal/filtering/http.go | 84 +- internal/filtering/safesearch.go | 382 +------- internal/filtering/safesearch/rules/bing.txt | 2 +- .../filtering/safesearch/rules/duckduckgo.txt | 2 +- .../filtering/safesearch/rules/google.txt | 2 +- .../filtering/safesearch/rules/pixabay.txt | 2 +- .../filtering/safesearch/rules/yandex.txt | 2 +- .../filtering/safesearch/rules/youtube.txt | 2 +- internal/filtering/safesearch/safesearch.go | 293 ++++-- .../safesearch/safesearch_internal_test.go | 137 +++ .../filtering/safesearch/safesearch_test.go | 175 ++-- internal/filtering/safesearchhttp.go | 71 ++ internal/filtering/servicelist.go | 113 ++- internal/home/auth.go | 77 +- internal/home/auth_test.go | 25 +- internal/home/authglinet.go | 4 +- internal/home/authglinet_test.go | 6 +- internal/home/client.go | 26 +- internal/home/clients.go | 77 +- internal/home/clients_test.go | 35 +- internal/home/clientshttp.go | 114 ++- internal/home/config.go | 40 +- internal/home/control.go | 86 +- internal/home/controlinstall.go | 8 +- internal/home/dns.go | 66 +- internal/home/home.go | 154 ++-- internal/home/mobileconfig.go | 5 +- internal/home/pprof.go | 39 + internal/home/tls.go | 6 +- internal/home/upgrade.go | 204 ++++- internal/home/upgrade_test.go | 245 ++++- internal/home/web.go | 45 +- internal/querylog/client.go | 1 + internal/querylog/decode.go | 187 ++-- internal/querylog/entry.go | 70 ++ internal/querylog/http.go | 179 +++- internal/querylog/json.go | 18 +- internal/querylog/qlog.go | 189 ++-- internal/querylog/qlog_test.go | 43 +- internal/querylog/qlogreader.go | 1 + internal/querylog/querylog.go | 57 +- internal/querylog/querylogfile.go | 56 +- internal/querylog/search.go | 28 +- internal/querylog/search_test.go | 3 +- internal/stats/http.go | 151 +++- internal/stats/http_test.go | 153 ++++ internal/stats/stats.go | 140 +-- internal/stats/stats_internal_test.go | 8 +- internal/stats/stats_test.go | 80 +- internal/stats/unit.go | 42 +- openapi/.gitignore | 2 - openapi/CHANGELOG.md | 165 ++++ openapi/index.html | 2 +- openapi/openapi.yaml | 219 ++++- scripts/README.md | 27 +- scripts/hooks/pre-commit | 2 +- scripts/make/build-docker.sh | 16 +- scripts/make/go-lint.sh | 3 +- scripts/make/txt-lint.sh | 27 +- scripts/querylog/.gitignore | 2 - scripts/querylog/anonymize.js | 1 - scripts/translations/.gitignore | 1 - scripts/translations/count.js | 41 - scripts/translations/download.js | 125 --- scripts/translations/main.go | 636 +++++++++++++ scripts/translations/package-lock.json | 838 ------------------ scripts/translations/package.json | 14 - scripts/translations/unused.js | 63 -- scripts/translations/upload.js | 47 - 181 files changed, 6992 insertions(+), 3430 deletions(-) create mode 100644 client/src/components/ProtectionTimer/index.js rename {scripts/make => docker}/Dockerfile (74%) create mode 100644 docker/dns-bind.awk create mode 100755 docker/healthcheck.sh create mode 100644 docker/web-bind.awk delete mode 100644 internal/aghos/endian_big.go delete mode 100644 internal/aghos/endian_little.go create mode 100644 internal/dhcpd/http_unix_test.go create mode 100644 internal/filtering/safesearch/safesearch_internal_test.go create mode 100644 internal/filtering/safesearchhttp.go create mode 100644 internal/home/pprof.go create mode 100644 internal/querylog/entry.go create mode 100644 internal/stats/http_test.go delete mode 100644 openapi/.gitignore delete mode 100644 scripts/querylog/.gitignore delete mode 100644 scripts/translations/.gitignore delete mode 100644 scripts/translations/count.js delete mode 100644 scripts/translations/download.js create mode 100644 scripts/translations/main.go delete mode 100644 scripts/translations/package-lock.json delete mode 100644 scripts/translations/package.json delete mode 100644 scripts/translations/unused.js delete mode 100644 scripts/translations/upload.js diff --git a/AGHTechDoc.md b/AGHTechDoc.md index 8f69e5bd..c1b53300 100644 --- a/AGHTechDoc.md +++ b/AGHTechDoc.md @@ -399,6 +399,7 @@ Response: "protection_enabled":true, "running":true, "dhcp_available":true, + "protection_disabled_duration":0 "version":"undefined" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e5395c6..d70ddb8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,15 +14,154 @@ and this project adheres to + + + + +## [v0.107.28] - 2023-04-12 + +See also the [v0.107.28 GitHub milestone][ms-v0.107.28]. + +### Added + +- The ability to exclude client activity from the query log or statistics by + using the new properties `ignore_querylog` and `ignore_statistics` of the + items of the `clients.persistent` array ([#1717], [#4299]). The UI changes + are coming in the upcoming releases. +- Better profiling information when `debug_pprof` is set to `true`. +- IPv6 support in Safe Search for some services. +- The ability to make bootstrap DNS lookups prefer IPv6 addresses to IPv4 ones + using the new `dns.bootstrap_prefer_ipv6` configuration file property + ([#4262]). +- Docker container's healthcheck ([#3290]). +- The new HTTP API `POST /control/protection`, that updates protection state + and adds an optional pause duration ([#1333]). The format of request body + is described in `openapi/openapi.yaml`. The duration of this pause could + also be set with the config field `protection_disabled_until` in `dns` + section of the YAML configuration file. +- The ability to create a static DHCP lease from a dynamic one more easily + ([#3459]). +- Two new HTTP APIs, `PUT /control/stats/config/update` and `GET + control/stats/config`, which can be used to set and receive the query log + configuration. See openapi/openapi.yaml for the full description. +- Two new HTTP APIs, `PUT /control/querylog/config/update` and `GET + control/querylog/config`, which can be used to set and receive the statistics + configuration. See openapi/openapi.yaml for the full description. +- The ability to set custom IP for EDNS Client Subnet by using the DNS-server + configuration section on the DNS settings page in the UI ([#1472]). +- The ability to manage safesearch for each service by using the new + `safe_search` field ([#1163]). + +### Changed + +- ARPA domain names containing a subnet within private networks now also + considered private, behaving closer to [RFC 6761][rfc6761] ([#5567]). + +#### Configuration Changes + +In this release, the schema version has changed from 17 to 20. + +- Property `statistics.interval`, which in schema versions 19 and earlier used + to be an integer number of days, is now a string with a human-readable + duration: + + ```yaml + # BEFORE: + 'statistics': + # … + 'interval': 1 + + # AFTER: + 'statistics': + # … + 'interval': '24h' + ``` + + To rollback this change, convert the property back into days and change the + `schema_version` back to `19`. +- The `dns.safesearch_enabled` field has been replaced with `safe_search` + object containing per-service settings. +- The `clients.persistent.safesearch_enabled` field has been replaced with + `safe_search` object containing per-service settings. + + ```yaml + # BEFORE: + 'safesearch_enabled': true + + # AFTER: + 'safe_search': + 'enabled': true + 'bing': true + 'duckduckgo': true + 'google': true + 'pixabay': true + 'yandex': true + 'youtube': true + ``` + + To rollback this change, move the value of `dns.safe_search.enabled` into the + `dns.safesearch_enabled`, then remove `dns.safe_search` field. Do the same + client's specific `clients.persistent.safesearch` and then change the + `schema_version` back to `17`. + +### Deprecated + +- The `POST /control/safesearch/enable` HTTP API is deprecated. Use the new + `PUT /control/safesearch/settings` API. +- The `POST /control/safesearch/disable` HTTP API is deprecated. Use the new + `PUT /control/safesearch/settings` API +- The `safesearch_enabled` field is deprecated in the following HTTP APIs: + - `GET /control/clients`; + - `POST /control/clients/add`; + - `POST /control/clients/update`; + - `GET /control/clients/find?ip0=...&ip1=...&ip2=...`. + + Check `openapi/openapi.yaml` for more details. +- The `GET /control/stats_info` HTTP API; use the new `GET + /control/stats/config` API instead. + + **NOTE:** If interval is custom then it will be equal to `90` days for + compatibility reasons. See openapi/openapi.yaml and `openapi/CHANGELOG.md`. +- The `POST /control/stats_config` HTTP API; use the new `PUT + /control/stats/config/update` API instead. +- The `GET /control/querylog_info` HTTP API; use the new `GET + /control/querylog/config` API instead. + + **NOTE:** If interval is custom then it will be equal to `90` days for + compatibility reasons. See openapi/openapi.yaml and `openapi/CHANGELOG.md`. +- The `POST /control/querylog_config` HTTP API; use the new `PUT + /control/querylog/config/update` API instead. + +### Fixed + +- Logging of the client's IP address after failed login attempts ([#5701]). + +[#1163]: https://github.com/AdguardTeam/AdGuardHome/issues/1163 +[#1333]: https://github.com/AdguardTeam/AdGuardHome/issues/1333 +[#1163]: https://github.com/AdguardTeam/AdGuardHome/issues/1717 +[#1472]: https://github.com/AdguardTeam/AdGuardHome/issues/1472 +[#3290]: https://github.com/AdguardTeam/AdGuardHome/issues/3290 +[#3459]: https://github.com/AdguardTeam/AdGuardHome/issues/3459 +[#4262]: https://github.com/AdguardTeam/AdGuardHome/issues/4262 +[#3290]: https://github.com/AdguardTeam/AdGuardHome/issues/4299 +[#5567]: https://github.com/AdguardTeam/AdGuardHome/issues/5567 +[#5701]: https://github.com/AdguardTeam/AdGuardHome/issues/5701 + +[ms-v0.107.28]: https://github.com/AdguardTeam/AdGuardHome/milestone/64?closed=1 +[rfc6761]: https://www.rfc-editor.org/rfc/rfc6761 + + ## [v0.107.27] - 2023-04-05 @@ -73,8 +212,6 @@ See also the [v0.107.26 GitHub milestone][ms-v0.107.26]. #### Configuration Changes -In this release, the schema version has changed from 16 to 17. - - Property `edns_client_subnet`, which in schema versions 16 and earlier used to be a part of the `dns` object, is now part of the `dns.edns_client_subnet` object: @@ -126,10 +263,6 @@ In this release, the schema version has changed from 16 to 17. [ms-v0.107.26]: https://github.com/AdguardTeam/AdGuardHome/milestone/62?closed=1 [rfc3696]: https://datatracker.ietf.org/doc/html/rfc3696 - - ## [v0.107.25] - 2023-02-21 @@ -1787,11 +1920,12 @@ See also the [v0.104.2 GitHub milestone][ms-v0.104.2]. -[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.27...HEAD +[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.28...HEAD +[v0.107.28]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.27...v0.107.28 [v0.107.27]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.26...v0.107.27 [v0.107.26]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.25...v0.107.26 [v0.107.25]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.107.24...v0.107.25 diff --git a/client/dev.eslintrc b/client/dev.eslintrc index 84ca4b39..27341caf 100644 --- a/client/dev.eslintrc +++ b/client/dev.eslintrc @@ -3,4 +3,4 @@ "rules": { "no-debugger":"warn", } -} \ No newline at end of file +} diff --git a/client/src/__locales/cs.json b/client/src/__locales/cs.json index 0931b6a1..444415e2 100644 --- a/client/src/__locales/cs.json +++ b/client/src/__locales/cs.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "Zapnutá Rodičovská kontrola", "disabled_safe_search_toast": "Vypnuté bezpečné vyhledávání", "enabled_save_search_toast": "Zapnuté bezpečné vyhledávání", + "updated_save_search_toast": "Nastavení Bezpečného vyhledávání aktualizováno", "enabled_table_header": "Zapnuto", "name_table_header": "Název", "list_url_table_header": "Seznam URL", @@ -290,6 +291,8 @@ "rate_limit": "Rychlostní limit", "edns_enable": "Povolit klientskou podsíť EDNS", "edns_cs_desc": "Přidá možnost podsítě klienta EDNS (ECS) do odchozích požadavků a zaznamá hodnoty odeslané klienty do protokolu dotazů.", + "edns_use_custom_ip": "Použít vlastní IP pro EDNS", + "edns_use_custom_ip_desc": "Povolit použití vlastní IP pro EDNS", "rate_limit_desc": "Počet požadavků za sekundu, které smí jeden klient provádět (0: neomezeno)", "blocking_ipv4_desc": "IP adresa, která se má vrátit v případě blokovaného požadavku typu A", "blocking_ipv6_desc": "IP adresa, která se má vrátit v případě blokovaného požadavku typu AAAA", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "Opravdu chcete změnit uchovávání statistik? Pokud snížíte hodnotu intervalu, některá data budou ztracena", "statistics_cleared": "Statistiky úspěšně vyčištěny", "statistics_enable": "Povolit statistiky", + "ignore_domains": "Ignorované domény (oddělené novým řádkem)", + "ignore_domains_title": "Ignorované domény", + "ignore_domains_desc_stats": "Dotazy pro tyto domény se do statistik nezapisují", + "ignore_domains_desc_query": "Dotazy pro tyto domény se do záznamu dotazů nezapisují", "interval_hours": "Hodiny: {{count}}", "interval_hours_plural": "Hodiny: {{count}}", "filters_configuration": "Konfigurace filtrů", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>Poznámka: Anonymizace IP je zapnuta. Můžete ji vypnout v <1>Obecných nastaveních.", "confirm_dns_cache_clear": "Opravdu chcete vymazat mezipaměť DNS?", "cache_cleared": "Mezipaměť DNS úspěšně vymazána", - "clear_cache": "Vymazat mezipaměť" + "clear_cache": "Vymazat mezipaměť", + "make_static": "Nastavit jako statickou", + "theme_auto_desc": "Automatický (podle barevného motivu vašeho zařízení)", + "theme_dark_desc": "Tmavý motiv", + "theme_light_desc": "Světlý motiv", + "disable_for_seconds": "Na {{count}} sek.", + "disable_for_seconds_plural": "Na {{count}} sek.", + "disable_for_minutes": "Na {{count}} min.", + "disable_for_minutes_plural": "Na {{count}} min.", + "disable_for_hours": "Na {{count}} hod.", + "disable_for_hours_plural": "Na {{count}} hod.", + "disable_until_tomorrow": "Do zítřka", + "disable_notify_for_seconds": "Vypnout ochranu na {{count}} sek.", + "disable_notify_for_seconds_plural": "Vypnout ochranu na {{count}} sek.", + "disable_notify_for_minutes": "Vypnout ochranu na {{count}} min.", + "disable_notify_for_minutes_plural": "Vypnout ochranu na {{count}} min.", + "disable_notify_for_hours": "Vypnout ochranu na {{count}} hod.", + "disable_notify_for_hours_plural": "Vypnout ochranu na {{count}} hod.", + "disable_notify_until_tomorrow": "Vypnout ochranu do zítřka", + "enable_protection_timer": "Ochrana bude zapnuta za {{time}}" } diff --git a/client/src/__locales/da.json b/client/src/__locales/da.json index 67288436..465143b5 100644 --- a/client/src/__locales/da.json +++ b/client/src/__locales/da.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "Forældrekontrol aktiveret", "disabled_safe_search_toast": "Sikker søgning deaktiveret", "enabled_save_search_toast": "Sikker søgning aktiveret", + "updated_save_search_toast": "Sikker søgning opdateret", "enabled_table_header": "Aktiveret", "name_table_header": "Navn", "list_url_table_header": "Liste-URL", @@ -290,6 +291,8 @@ "rate_limit": "Hyppighedsgrænse", "edns_enable": "Aktivér EDNS-klientundernet", "edns_cs_desc": "Tilføj indstillingen EDNS Client Subnet (ECS) til upstream-forespørgsler og log de af klienterne sendte værdier i forespørgselsloggen.", + "edns_use_custom_ip": "Brug tilpasset IP til EDNS", + "edns_use_custom_ip_desc": "Tillad brug af tilpasset IP til EDNS", "rate_limit_desc": "Antallet af forespørgsler pr. sekund tilladt pr. klient (værdien 0 = ubegrænset)", "blocking_ipv4_desc": "Returneret IP-adresse for en blokeret A-forespørgsel", "blocking_ipv6_desc": "Returneret IP-adresse for en blokeret AAAA-forespørgsel", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "Sikker på, at du vil ændre på statistikbevaring? Mindskes intervalværdien, vil nogle data gå tabt", "statistics_cleared": "Statistikkerne er ryddet", "statistics_enable": "Aktivér statistikker", + "ignore_domains": "Ignorerede domæner (adskilt af ny linje)", + "ignore_domains_title": "Ignorerede domæner", + "ignore_domains_desc_stats": "Forespørgsler til disse domæner opføres ikke i statistikken", + "ignore_domains_desc_query": "Forespørgsler til disse domæner opføres ikke i forespørgselsloggen", "interval_hours": "{{count}} time", "interval_hours_plural": "{{count}} timer", "filters_configuration": "Filteropsætninger", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>Bemærk: IP-anonymisering er aktiveret. Det kan deaktiveres via <1>Generelle indstillinger.", "confirm_dns_cache_clear": "Sikker på, at DNS-cache skal ryddes?", "cache_cleared": "DNS-cache hermed ryddet", - "clear_cache": "Ryd cache" + "clear_cache": "Ryd cache", + "make_static": "Gør statisk", + "theme_auto_desc": "Auto (baseret på enhedens farveskema)", + "theme_dark_desc": "Mørkt tema", + "theme_light_desc": "Lyst tema", + "disable_for_seconds": "I {{count}} sekund", + "disable_for_seconds_plural": "I {{count}} sekunder", + "disable_for_minutes": "I {{count}} minut", + "disable_for_minutes_plural": "I {{count}} minutter", + "disable_for_hours": "I {{count}} time", + "disable_for_hours_plural": "I {{count}} timer", + "disable_until_tomorrow": "Indtil i morgen", + "disable_notify_for_seconds": "Deaktivere beskyttelse i {{count}} sekund", + "disable_notify_for_seconds_plural": "Deaktivere beskyttelse i {{count}} sekunder", + "disable_notify_for_minutes": "Deaktivere beskyttelse i {{count}} minut", + "disable_notify_for_minutes_plural": "Deaktivere beskyttelse i {{count}} minutter", + "disable_notify_for_hours": "Deaktivere beskyttelse i {{count}} time", + "disable_notify_for_hours_plural": "Deaktivere beskyttelse i {{count}} timer", + "disable_notify_until_tomorrow": "Deaktiver beskyttelse indtil i morgen", + "enable_protection_timer": "Beskyttelse deaktiveres om {{time}}" } diff --git a/client/src/__locales/de.json b/client/src/__locales/de.json index 3bbb7aff..b7d59a9c 100644 --- a/client/src/__locales/de.json +++ b/client/src/__locales/de.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "Kindersicherung aktiviert", "disabled_safe_search_toast": "Sichere Suche deaktiviert", "enabled_save_search_toast": "Sichere Suche aktiviert", + "updated_save_search_toast": "Einstellungen für die sichere Suche aktualisiert", "enabled_table_header": "Aktiviert", "name_table_header": "Name", "list_url_table_header": "Adressliste", @@ -290,6 +291,8 @@ "rate_limit": "Begrenzungswert", "edns_enable": "EDNS Client Subnetz aktivieren", "edns_cs_desc": "Die Option EDNS Client Subnetz (ECS) zu Upstream-Anfragen hinzufügen und die von Clients gesendeten Werte protokollieren.", + "edns_use_custom_ip": "Benutzerdefinierte IP für EDNS verwenden", + "edns_use_custom_ip_desc": "Benutzerdefinierte IP für EDNS zulassen", "rate_limit_desc": "Die Anzahl der Anfragen pro Sekunde, die ein einzelner Client stellen darf. Das Setzen auf 0 bedeutet keine Begrenzung.", "blocking_ipv4_desc": "IP-Adresse, die für eine gesperrte A-Anfrage zurückgegeben werden soll", "blocking_ipv6_desc": "IP-Adresse, die für eine gesperrte AAAA-Anfrage zurückgegeben werden soll", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "Möchten Sie wirklich die Aufbewahrung der Statistiken ändern? Wenn Sie den Zeitabstand verringern, gehen einige Daten verloren.", "statistics_cleared": "Statistiken wurden erfolgreich gelöscht", "statistics_enable": "Statistiken aktivieren", + "ignore_domains": "Ignorierte Domains (durch Zeilenumbruch getrennt)", + "ignore_domains_title": "Ignorierte Domains", + "ignore_domains_desc_stats": "Abfragen für diese Domains werden nicht in die Statistik aufgenommen", + "ignore_domains_desc_query": "Abfragen für diese Domains werden nicht in das Abfrageprotokoll aufgenommen", "interval_hours": "{{count}} Stunde", "interval_hours_plural": "{{count}} Stunden", "filters_configuration": "Filterkonfiguration", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>Hinweis: Die IP-Anonymisierung ist aktiviert. Sie können sie in den <1>Allgemeinen Einstellungen deaktivieren.", "confirm_dns_cache_clear": "Möchten Sie den DNS-Cache wirklich leeren?", "cache_cleared": "DNS-Cache erfolgreich geleert", - "clear_cache": "Cache leeren" + "clear_cache": "Cache leeren", + "make_static": "Statisch machen", + "theme_auto_desc": "Automatisch (basierend auf dem Farbschema Ihres Geräts)", + "theme_dark_desc": "Dunkles Farbschema", + "theme_light_desc": "Helles Farbschema", + "disable_for_seconds": "Für {{count}} Sekunde", + "disable_for_seconds_plural": "Für {{count}} Sekunden", + "disable_for_minutes": "Für {{count}} Minute", + "disable_for_minutes_plural": "Für {{count}} Minuten", + "disable_for_hours": "Für {{count}} Stunde", + "disable_for_hours_plural": "Für {{count}} Stunden", + "disable_until_tomorrow": "Bis morgen", + "disable_notify_for_seconds": "Schutz für {{count}} Sekunde deaktivieren", + "disable_notify_for_seconds_plural": "Schutz für {{count}} Sekunden deaktivieren", + "disable_notify_for_minutes": "Schutz für {{count}} Minute deaktivieren", + "disable_notify_for_minutes_plural": "Schutz für {{count}} Minuten deaktivieren", + "disable_notify_for_hours": "Schutz für {{count}} Stunde deaktivieren", + "disable_notify_for_hours_plural": "Schutz für {{count}} Stunden deaktivieren", + "disable_notify_until_tomorrow": "Schutz bis morgen deaktivieren", + "enable_protection_timer": "Der Schutz wird in {{time}} wieder aktiviert" } diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json index 2afa38bd..14bd92e7 100644 --- a/client/src/__locales/en.json +++ b/client/src/__locales/en.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "Enabled Parental Control", "disabled_safe_search_toast": "Disabled Safe Search", "enabled_save_search_toast": "Enabled Safe Search", + "updated_save_search_toast": "Safe Search settings updated", "enabled_table_header": "Enabled", "name_table_header": "Name", "list_url_table_header": "List URL", @@ -290,6 +291,8 @@ "rate_limit": "Rate limit", "edns_enable": "Enable EDNS client subnet", "edns_cs_desc": "Add the EDNS Client Subnet option (ECS) to upstream requests and log the values sent by the clients in the query log.", + "edns_use_custom_ip": "Use custom IP for EDNS", + "edns_use_custom_ip_desc": "Allow to use custom IP for EDNS", "rate_limit_desc": "The number of requests per second allowed per client. Setting it to 0 means no limit.", "blocking_ipv4_desc": "IP address to be returned for a blocked A request", "blocking_ipv6_desc": "IP address to be returned for a blocked AAAA request", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "Are you sure you want to change statistics retention? If you decrease the interval value, some data will be lost", "statistics_cleared": "Statistics successfully cleared", "statistics_enable": "Enable statistics", + "ignore_domains": "Ignored domains (separated by newline)", + "ignore_domains_title": "Ignored domains", + "ignore_domains_desc_stats": "Queries for these domains are not written to the statistics", + "ignore_domains_desc_query": "Queries for these domains are not written to the query log", "interval_hours": "{{count}} hour", "interval_hours_plural": "{{count}} hours", "filters_configuration": "Filters configuration", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>Note: IP anonymization is enabled. You can disable it in <1>General settings.", "confirm_dns_cache_clear": "Are you sure you want to clear DNS cache?", "cache_cleared": "DNS cache successfully cleared", - "clear_cache": "Clear cache" + "clear_cache": "Clear cache", + "make_static": "Make static", + "theme_auto_desc": "Auto (based on the color scheme of your device)", + "theme_dark_desc": "Dark theme", + "theme_light_desc": "Light theme", + "disable_for_seconds": "For {{count}} second", + "disable_for_seconds_plural": "For {{count}} seconds", + "disable_for_minutes": "For {{count}} minute", + "disable_for_minutes_plural": "For {{count}} minutes", + "disable_for_hours": "For {{count}} hour", + "disable_for_hours_plural": "For {{count}} hours", + "disable_until_tomorrow": "Until tomorrow", + "disable_notify_for_seconds": "Disable protection for {{count}} second", + "disable_notify_for_seconds_plural": "Disable protection for {{count}} seconds", + "disable_notify_for_minutes": "Disable protection for {{count}} minute", + "disable_notify_for_minutes_plural": "Disable protection for {{count}} minutes", + "disable_notify_for_hours": "Disable protection for {{count}} hour", + "disable_notify_for_hours_plural": "Disable protection for {{count}} hours", + "disable_notify_until_tomorrow": "Disable protection until tomorrow", + "enable_protection_timer": "Protection will be enabled in {{time}}" } diff --git a/client/src/__locales/es.json b/client/src/__locales/es.json index f0238614..2e112cd3 100644 --- a/client/src/__locales/es.json +++ b/client/src/__locales/es.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "Control parental habilitado", "disabled_safe_search_toast": "Búsqueda segura deshabilitada", "enabled_save_search_toast": "Búsqueda segura habilitada", + "updated_save_search_toast": "Configuración de búsqueda segura actualizada", "enabled_table_header": "Habilitado", "name_table_header": "Nombre", "list_url_table_header": "URL de la lista", @@ -290,6 +291,8 @@ "rate_limit": "Límite de cantidad", "edns_enable": "Habilitar subred de cliente EDNS", "edns_cs_desc": "Añade la opción subred de cliente EDNS (ECS) a las peticiones del DNS de subida y registra los valores enviados por los clientes en el registro de consultas.", + "edns_use_custom_ip": "Usar IP personalizada para EDNS", + "edns_use_custom_ip_desc": "Permitir el uso de IP personalizadas para EDNS", "rate_limit_desc": "Número de peticiones por segundo permitidas por cliente. Establecerlo en 0 significa que no hay límite.", "blocking_ipv4_desc": "Dirección IP devolverá una petición A bloqueada", "blocking_ipv6_desc": "Dirección IP devolverá una petición AAAA bloqueada", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "¿Estás seguro de que deseas cambiar la retención de estadísticas? Si disminuye el valor del intervalo, se perderán algunos datos", "statistics_cleared": "Estadísticas borradas correctamente", "statistics_enable": "Habilitar estadísticas", + "ignore_domains": "Dominios ignorados (separados por una nueva línea)", + "ignore_domains_title": "Dominios ignorados", + "ignore_domains_desc_stats": "Las consultas para estos dominios no aparecen en las estadísticas", + "ignore_domains_desc_query": "Las consultas para estos dominios no aparecen en el registro de consultas", "interval_hours": "{{count}} hora", "interval_hours_plural": "{{count}} horas", "filters_configuration": "Configuración de filtros", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>Nota: La anonimización de IP está habilitada. Puedes deshabilitarla en <1>Configuración general.", "confirm_dns_cache_clear": "¿Estás seguro de que deseas borrar la caché DNS?", "cache_cleared": "Caché DNS borrado correctamente", - "clear_cache": "Borrar caché" + "clear_cache": "Borrar caché", + "make_static": "Hacer estático", + "theme_auto_desc": "Automático (basado en el esquema de colores de tu dispositivo)", + "theme_dark_desc": "Tema oscuro", + "theme_light_desc": "Tema claro", + "disable_for_seconds": "Por {{count}} segundo", + "disable_for_seconds_plural": "Por {{count}} segundos", + "disable_for_minutes": "Por {{count}} minuto", + "disable_for_minutes_plural": "Por {{count}} minutos", + "disable_for_hours": "Por {{count}} hora", + "disable_for_hours_plural": "Por {{count}} horas", + "disable_until_tomorrow": "Hasta mañana", + "disable_notify_for_seconds": "Desactivar la protección por {{count}} segundo", + "disable_notify_for_seconds_plural": "Desactivar la protección por {{count}} segundos", + "disable_notify_for_minutes": "Desactivar la protección por {{count}} minuto", + "disable_notify_for_minutes_plural": "Desactivar la protección por {{count}} minutos", + "disable_notify_for_hours": "Desactivar la protección por {{count}} hora", + "disable_notify_for_hours_plural": "Desactivar la protección por {{count}} horas", + "disable_notify_until_tomorrow": "Desactivar la protección hasta mañana", + "enable_protection_timer": "La protección se activará en {{time}}" } diff --git a/client/src/__locales/fi.json b/client/src/__locales/fi.json index b04ad021..e74f05d5 100644 --- a/client/src/__locales/fi.json +++ b/client/src/__locales/fi.json @@ -9,12 +9,12 @@ "bootstrap_dns": "Bootstrap DNS-palvelimet", "bootstrap_dns_desc": "Bootstrap DNS-palvelimia käytetään ylävirroiksi määritettyjen DoH/DoT-resolvereiden IP-osoitteiden selvitykseen.", "local_ptr_title": "Yksityiset käänteiset DNS-palvelimet", - "local_ptr_desc": "DNS-palvelimet, joita AdGuard Home käyttää paikallisille PTR-kyselyille. Näitä palvelimia käytetään yksityistä IP-osoitetta käyttävien PTR-kyselyiden osoitteiden, kuten \"192.168.12.34\", selvitykseen käänteisen DNS:n avulla. Jos ei käytössä, AdGuard Home käyttää käyttöjärjestelmän oletusarvoisia DNS-resolvereita, poislukien AdGuard Homen omat osoitteet.", + "local_ptr_desc": "DNS-palvelimet, joita AdGuard Home käyttää paikallisille PTR-pyynnöille. Näitä palvelimia käytetään yksityistä IP-osoitetta käyttävien PTR-pyyntöjen osoitteiden, kuten \"192.168.12.34\", selvitykseen käänteisen DNS:n avulla. Jos ei käytössä, AdGuard Home käyttää käyttöjärjestelmän oletusarvoisia DNS-resolvereita, poislukien AdGuard Homen omat osoitteet.", "local_ptr_default_resolver": "Oletusarvoisesti AdGuard Home käyttää seuraavia käänteisiä DNS-resolvereita: {{ip}}.", "local_ptr_no_default_resolver": "AdGuard Home ei voinut määrittää tälle järjestelmälle sopivaa yksityistä käänteistä DNS-resolveria.", "local_ptr_placeholder": "Syötä yksi palvelimen osoite per rivi", "resolve_clients_title": "Käytä päätelaitteiden IP-osoitteille käänteistä selvitystä", - "resolve_clients_desc": "Selvitä päätelaitteiden IP-osoitteiden isäntänimet käänteisesti lähettämällä PTR-kyselyt sopiville resolvereille (yksityiset DNS-palvelimet paikallisille päätelaitteille, lähtevät palvelimet päätelaitteille, joilla on julkiset IP-osoitteet).", + "resolve_clients_desc": "Selvitä päätelaitteiden IP-osoitteiden isäntänimet käänteisesti lähettämällä PTR-pyynnöt sopiville resolvereille (yksityiset DNS-palvelimet paikallisille päätelaitteille, lähtevät palvelimet päätelaitteille, joilla on julkiset IP-osoitteet).", "use_private_ptr_resolvers_title": "Käytä yksityisiä käänteisiä DNS-resolvereita", "use_private_ptr_resolvers_desc": "Suorita käänteiset DNS-selvitykset paikallisesti tarjotuille osoitteille käyttäen näitä ylävirran palvelimia. Jos ei käytössä, vastaa AdGuard Home kaikkiin sen tyyppisiin PTR-pyyntöihin NXDOMAIN-arvolla, pois lukien DHCP, /etc/hosts, yms. -tiedoista tunnistettut päätelaitteet.", "check_dhcp_servers": "Etsi DHCP-palvelimia", @@ -75,7 +75,7 @@ "dhcp_add_static_lease": "Lisää kiinteä laina", "dhcp_reset_leases": "Tyhjennä kaikki lainat", "dhcp_reset_leases_confirm": "Haluatko varmasti tyhjentää kaikki lainat?", - "dhcp_reset_leases_success": "DHCP-lainat tyhjennettiin", + "dhcp_reset_leases_success": "DHCP-lainojen tyhjennys onnistui", "dhcp_reset": "Haluatko varmasti palauttaa DHCP-asetukset?", "country": "Maa", "city": "Kaupunki", @@ -167,10 +167,11 @@ "enabled_parental_toast": "Lapsilukko otettiin käyttöön", "disabled_safe_search_toast": "Turvallinen haku poistettiin käytöstä", "enabled_save_search_toast": "Turvallinen haku otettiin käyttöön", + "updated_save_search_toast": "Turvallisen haun asetukset päivitettiin", "enabled_table_header": "Käytössä", "name_table_header": "Nimi", "list_url_table_header": "Listan URL", - "rules_count_table_header": "Sääntöjä", + "rules_count_table_header": "Sääntöjen määrä", "last_time_updated_table_header": "Viimeisin päivitys", "actions_table_header": "Toiminnot", "request_table_header": "Pyyntö", @@ -253,8 +254,8 @@ "query_log_response_status": "Tila: {{value}}", "query_log_filtered": "Suodattanut {{filter}}", "query_log_confirm_clear": "Haluatko varmasti tyhjentää pyyntöhistorian?", - "query_log_cleared": "Pyyntöhistoria tyhjennettiin", - "query_log_updated": "Pyyntöhistoria päivitettiin", + "query_log_cleared": "Pyyntöhistorian tyhjennys onnistui", + "query_log_updated": "Pyyntöhistorian päivitys onnistui", "query_log_clear": "Tyhjennä pyyntöhistoria", "query_log_retention": "Pyyntöhistorian säilytys", "query_log_enable": "Käytä historiaa", @@ -290,6 +291,8 @@ "rate_limit": "Pyyntöjen ajoitus", "edns_enable": "Käytä EDNS-päätelaitealivekkoa", "edns_cs_desc": "Lähetä päätelaitteiden aliverkot DNS-palvelimille.", + "edns_use_custom_ip": "Käytä omaa IP-osoitetta EDNS:lle", + "edns_use_custom_ip_desc": "Salli oman IP-osoitteen käyttö EDNS-mekanismille.", "rate_limit_desc": "Päätelaitteelle sallittu pyyntöjen enimmäismäärä sekunnissa. Arvo 0 tarkoittaa rajatonta.", "blocking_ipv4_desc": "Estettyyn A-pyyntöön palautettava IP-osoite", "blocking_ipv6_desc": "Estettyyn AAAA-pyyntöön palautettava IP-osoite", @@ -367,7 +370,7 @@ "encryption_config_saved": "Salausasetukset tallennettiin", "encryption_server": "Palvelimen nimi", "encryption_server_enter": "Syötä verkkotunnuksesi", - "encryption_server_desc": "Jos määritetty, AdGuard Home tunnistaa ClientID-tunnisteet, vastaa DDR-kyselyihin ja suorittaa yhteyden lisätarkistuksia. Jos ei määritetty, nämä ominaisuudet eivät ole käytössä. On vastattava yhtä varmenteen DNS-nimistä.", + "encryption_server_desc": "Jos määritetty, AdGuard Home tunnistaa ClientID-tunnisteet, vastaa DDR-pyyntöihin ja suorittaa yhteyden lisätarkistuksia. Jos ei määritetty, nämä ominaisuudet eivät ole käytössä. On vastattava yhtä varmenteen DNS-nimistä.", "encryption_redirect": "Automaattinen HTTPS-ohjaus", "encryption_redirect_desc": "Jos käytössä, AdGuard Home ohjaa HTTP-osoitteet automaattisesti HTTPS-osoitteisiin.", "encryption_https": "HTTPS-portti", @@ -416,7 +419,7 @@ "clients_title": "Pysyvät päätelaitteet", "clients_desc": "Määritä pysyvät AdGuard Homeen yhdistetyt päätelaitetiedot.", "settings_global": "Yleinen", - "settings_custom": "Muut aiheet", + "settings_custom": "Mukautettu", "table_client": "Asiakas", "table_name": "Nimi", "save_btn": "Tallenna", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "Haluatko varmasti muuttaa tilastojen säilytysaikaa? Jos aikaa lyhennetään, joitakin tietoja menetetään.", "statistics_cleared": "Tilastot tyhjennettiin", "statistics_enable": "Ota tilastointi käyttöön", + "ignore_domains": "Ohitettavat verkkotunnukset (erotettu rivinvaihdolla)", + "ignore_domains_title": "Ohitettavat verkkotunnukset", + "ignore_domains_desc_stats": "Näihin verkkotunnuksiin lähetettyjä pyyntöjä ei tallenneta tilastoihin.", + "ignore_domains_desc_query": "Näihin verkkotunnuksiin lähetettyjä pyyntöjä ei tallenneta pyyntöhistoriaan.", "interval_hours": "{{count}} tunti", "interval_hours_plural": "{{count}} tuntia", "filters_configuration": "Suodatinten määritys", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>Huomioi: IP-osoitteen anonymisointi on käytössä. Voit poistaa sen käytöstä <1>Yleisistä asetuksista.", "confirm_dns_cache_clear": "Haluatko varmasti tyhjentää DNS-välimuistin?", "cache_cleared": "DNS-välimuistin tyhjennys onnistui", - "clear_cache": "Tyhjennä välimuisti" + "clear_cache": "Tyhjennä välimuisti", + "make_static": "Tallenna kiinteäksi", + "theme_auto_desc": "Automaattinen (seuraa laitteen väriteemaa)", + "theme_dark_desc": "Tumma teema", + "theme_light_desc": "Vaalea teema", + "disable_for_seconds": "{{count}} sekunniksi", + "disable_for_seconds_plural": "{{count}} sekunniksi", + "disable_for_minutes": "{{count}} minuutiksi", + "disable_for_minutes_plural": "{{count}} minuutiksi", + "disable_for_hours": "{{count}} tunniksi", + "disable_for_hours_plural": "{{count}} tunniksi", + "disable_until_tomorrow": "Huomiseen asti", + "disable_notify_for_seconds": "Poista suojaus käytöstä {{count}} sekunniksi", + "disable_notify_for_seconds_plural": "Poista suojaus käytöstä {{count}} sekunniksi", + "disable_notify_for_minutes": "Poista suojaus käytöstä {{count}} minuutiksi", + "disable_notify_for_minutes_plural": "Poista suojaus käytöstä {{count}} minuutiksi", + "disable_notify_for_hours": "Poista suojaus käytöstä {{count}} tunniksi", + "disable_notify_for_hours_plural": "Poista suojaus käytöstä {{count}} tunniksi", + "disable_notify_until_tomorrow": "Poista suojaus käytöstä huomiseen asti", + "enable_protection_timer": "Suojaus otetaan käyttöön {{time}} kuluttua" } diff --git a/client/src/__locales/fr.json b/client/src/__locales/fr.json index a99e2baa..b514ca87 100644 --- a/client/src/__locales/fr.json +++ b/client/src/__locales/fr.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "Contrôle Parental activé", "disabled_safe_search_toast": "Recherche Sécurisée désactivée", "enabled_save_search_toast": "Recherche Sécurisée activée", + "updated_save_search_toast": "Les paramètres de Recherche sécurisée sont mis à jour", "enabled_table_header": "Activé", "name_table_header": "Nom", "list_url_table_header": "URL de la liste", @@ -290,6 +291,8 @@ "rate_limit": "Limite de taux", "edns_enable": "Activer le sous-réseau du client EDNS", "edns_cs_desc": "Ajouter l'option du sous-réseau Client EDNS (ECS) au requêtes en amont et enregistrer les valeurs envoyées par les clients dans le journal des requêtes.", + "edns_use_custom_ip": "Utiliser une IP personnalisée pour EDNS", + "edns_use_custom_ip_desc": "Autoriser l'utilisation d'une adresse IP personnalisée pour EDNS", "rate_limit_desc": "Le nombre de requêtes par seconde qu’un seul client est autorisé à faire. Le réglage 0 fait illimité.", "blocking_ipv4_desc": "Adresse IP à renvoyer pour une demande A bloquée", "blocking_ipv6_desc": "Adresse IP à renvoyer pour une demande AAAA bloquée", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "Êtes-vous sûr de vouloir modifier le maintien des statistiques ? Si vous diminuez la valeur de l'intervalle, certaines données seront perdues", "statistics_cleared": "Statistiques effacées", "statistics_enable": "Activer les statistiques", + "ignore_domains": "Domaines ignorés (séparés par une nouvelle ligne)", + "ignore_domains_title": "Domaines ignorés", + "ignore_domains_desc_stats": "Les requêtes pour ces domaines ne sont pas écrites dans les statistiques", + "ignore_domains_desc_query": "Les requêtes pour ces domaines ne sont pas écrites dans le journal des requêtes", "interval_hours": "{{count}} heure", "interval_hours_plural": "{{count}} heures", "filters_configuration": "Configuration des filtres", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>Note : L'anonymisation IP est activée. Vous pouvez la désactiver dans les <1>paramètres généraux.", "confirm_dns_cache_clear": "Voulez-vous vraiment vider le cache DNS ?", "cache_cleared": "Le cache DNS a été vidé", - "clear_cache": "Vider le cache" + "clear_cache": "Vider le cache", + "make_static": "Rendre statique", + "theme_auto_desc": "Auto (en fonction de la palette de couleurs de votre appareil)", + "theme_dark_desc": "Thème sombre", + "theme_light_desc": "Thème clair", + "disable_for_seconds": "Pendant {{count}} seconde", + "disable_for_seconds_plural": "Pendant {{count}} secondes", + "disable_for_minutes": "Pendant {{count}} minute", + "disable_for_minutes_plural": "Pendant {{count}} minutes", + "disable_for_hours": "Pendant {{count}} heure", + "disable_for_hours_plural": "Pendant {{count}} heures", + "disable_until_tomorrow": "Jusqu'à demain", + "disable_notify_for_seconds": "Désactiver la protection pendant {{count}} seconde", + "disable_notify_for_seconds_plural": "Désactiver la protection pendant {{count}} secondes", + "disable_notify_for_minutes": "Désactiver la protection pendant {{count}} minute", + "disable_notify_for_minutes_plural": "Désactiver la protection pendant {{count}} minutes", + "disable_notify_for_hours": "Désactiver la protection pendant {{count}} heure", + "disable_notify_for_hours_plural": "Désactiver la protection pendant {{count}} heures", + "disable_notify_until_tomorrow": "Désactiver la protection jusqu'à demain", + "enable_protection_timer": "La protection sera activée dans {{time}}" } diff --git a/client/src/__locales/hr.json b/client/src/__locales/hr.json index 0aef21df..d7784998 100644 --- a/client/src/__locales/hr.json +++ b/client/src/__locales/hr.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "Omogućen roditeljski nadzor", "disabled_safe_search_toast": "Onemogućeno sigurno pretraživanje", "enabled_save_search_toast": "Omogućeno sigurno pretraživanje", + "updated_save_search_toast": "Ažurirane postavke sigurnog pretraživanja", "enabled_table_header": "Omogućeno", "name_table_header": "Naziv", "list_url_table_header": "URL popisa", @@ -290,6 +291,8 @@ "rate_limit": "Ograničenje", "edns_enable": "Omogući podmrežu klijenta EDNS-a", "edns_cs_desc": "Dodajte opciju EDNS klijentske podmreže (ECS) uzvodnim zahtjevima i zabilježite vrijednosti koje su klijenti poslali u dnevnik upita.", + "edns_use_custom_ip": "Koristi prilagođeni IP za EDNS", + "edns_use_custom_ip_desc": "Dopusti korištenje prilagođenog IP-a za EDNS", "rate_limit_desc": "Broj zahtjeva u sekundi koji su dopušteni po jednom klijentu. Postavljanje na 0 znači neograničeno.", "blocking_ipv4_desc": "Povratna IP adresa za blokirane A zahtjeve", "blocking_ipv6_desc": "Povratna IP adresa za blokirane AAAA zahtjeve", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "Jeste li sigurni da želite promijeniti zadržavanje statistike? Ako smanjite vrijednost intervala, neki će podaci biti izgubljeni", "statistics_cleared": "Statistika je uspješno uklonjenja", "statistics_enable": "Omogući statistiku", + "ignore_domains": "Zanemarene domene (odvojene novim retkom)", + "ignore_domains_title": "Zanemarene domene", + "ignore_domains_desc_stats": "Upiti za ove domene ne upisuju se u statistiku", + "ignore_domains_desc_query": "Upiti za te domene nisu zapisani u zapisnik upita", "interval_hours": "{{count}} sata/i", "interval_hours_plural": "{{count}} sata/i", "filters_configuration": "Postavke filtara", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>Napomena:IP anonimizacija je omogućena. Možete ju onemogućiti u <1>općim postavkama.", "confirm_dns_cache_clear": "Jeste li sigurni da želite očistiti DNS predmemoriju?", "cache_cleared": "DNS predmemorija je uspješno izbrisana", - "clear_cache": "Očisti predmemoriju" + "clear_cache": "Očisti predmemoriju", + "make_static": "Učini statičnim", + "theme_auto_desc": "Automatski (na temelju sheme boja vašeg uređaja)", + "theme_dark_desc": "Tamna tema", + "theme_light_desc": "Svijetla tema", + "disable_for_seconds": "Za {{count}} sekundi", + "disable_for_seconds_plural": "Za {{count}} sekundi", + "disable_for_minutes": "Za {{count}} minuta", + "disable_for_minutes_plural": "Za {{count}} minuta", + "disable_for_hours": "Za {{count}} sati", + "disable_for_hours_plural": "Za {{count}} sati", + "disable_until_tomorrow": "Do sutra", + "disable_notify_for_seconds": "Isključi zaštitu na {{count}} sekundi", + "disable_notify_for_seconds_plural": "Onemogući zaštitu na {{count}} sekundi", + "disable_notify_for_minutes": "Isključi zaštitu na {{count}} minuta", + "disable_notify_for_minutes_plural": "Isključi zaštitu na {{count}} minuta", + "disable_notify_for_hours": "Isključi zaštitu na {{count}} sati", + "disable_notify_for_hours_plural": "Isključi zaštitu na {{count}} sati", + "disable_notify_until_tomorrow": "Isključi zaštitu do sutra", + "enable_protection_timer": "Zaštita će biti omogućena u {{time}}" } diff --git a/client/src/__locales/it.json b/client/src/__locales/it.json index e09fd79c..b2b2c143 100644 --- a/client/src/__locales/it.json +++ b/client/src/__locales/it.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "Il Controllo Parentale è attivo", "disabled_safe_search_toast": "La Ricerca Sicura è disattivata", "enabled_save_search_toast": "La Ricerca Sicura è attiva", + "updated_save_search_toast": "Impostazioni di Safe Search aggiornate", "enabled_table_header": "Attivo", "name_table_header": "Nome", "list_url_table_header": "Elenco URL", @@ -290,6 +291,8 @@ "rate_limit": "Limite delle richieste", "edns_enable": "Attiva client di sottorete EDNS", "edns_cs_desc": "Aggiunge l'opzione EDNS Client Subnet (ECS) alle richieste upstream e registra i valori inviati dai client nel registro delle richieste.", + "edns_use_custom_ip": "Usa IP personalizzato per EDNS", + "edns_use_custom_ip_desc": "Consentire l'uso di un IP personalizzato per EDNS", "rate_limit_desc": "Il numero di richieste al secondo consentite da un singolo client. Impostare questo valore a 0 rimuove le limitazioni.", "blocking_ipv4_desc": "Indirizzo IP per una richiesta DNS IPv4 bloccata", "blocking_ipv6_desc": "Indirizzo IP restituito per una richiesta DNS IPv6 bloccata", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "Sei sicuro di voler modificare la conservazione delle statistiche? Se il valore di intervallo dovesse diminuire, alcuni dati andranno persi", "statistics_cleared": "Statistiche azzerate correttamente", "statistics_enable": "Attiva statistiche", + "ignore_domains": "Domini ignorati (separati da nuova riga)", + "ignore_domains_title": "Domini ignorati", + "ignore_domains_desc_stats": "Le richieste per questi domini non vengono scritte nelle statistiche", + "ignore_domains_desc_query": "Le richieste per questi domini non vengono scritte nel registro delle richieste", "interval_hours": "{{count}} ora", "interval_hours_plural": "{{count}} ore", "filters_configuration": "Configurazione filtri", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>Attenzione: L'anonimizzazione dell'IP è abilitata. Puoi disabilitarla in <1>Impostazioni generali.", "confirm_dns_cache_clear": "Sei sicuro di voler cancellare la cache DNS?", "cache_cleared": "Cache DNS è stata cancellata correttamente", - "clear_cache": "Cancella cache" + "clear_cache": "Cancella cache", + "make_static": "Rendere statico", + "theme_auto_desc": "Auto (in base alla combinazione di colori del tuo dispositivo)", + "theme_dark_desc": "Tema scuro", + "theme_light_desc": "Tema chiaro", + "disable_for_seconds": "Per {{count}} secondo", + "disable_for_seconds_plural": "Per {{count}} secondi", + "disable_for_minutes": "Per {{count}} minuto", + "disable_for_minutes_plural": "Per {{count}} minuti", + "disable_for_hours": "Per {{count}} ora", + "disable_for_hours_plural": "Per {{count}} ore", + "disable_until_tomorrow": "Fino a domani", + "disable_notify_for_seconds": "Disattiva la protezione per {{count}} secondo", + "disable_notify_for_seconds_plural": "Disattiva la protezione per {{count}} secondi", + "disable_notify_for_minutes": "Disattiva protezione per {{count}} minuto", + "disable_notify_for_minutes_plural": "Disattiva la protezione per {{count}} minuti", + "disable_notify_for_hours": "Disattiva la protezione per {{count}} ora", + "disable_notify_for_hours_plural": "Disattiva la protezione per {{count}} ore", + "disable_notify_until_tomorrow": "Disattiva la protezione fino a domani", + "enable_protection_timer": "La protezione verrà attivata in {{time}}" } diff --git a/client/src/__locales/ja.json b/client/src/__locales/ja.json index 1ae0a1f8..08a6f4e3 100644 --- a/client/src/__locales/ja.json +++ b/client/src/__locales/ja.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "ペアレンタルコントロールが有効になりました", "disabled_safe_search_toast": "セーフサーチが無効になりました", "enabled_save_search_toast": "セーフサーチが有効になりました", + "updated_save_search_toast": "セーフ サーチの設定が更新されました。", "enabled_table_header": "有効", "name_table_header": "名称", "list_url_table_header": "URLリスト", @@ -290,6 +291,8 @@ "rate_limit": "頻度制限", "edns_enable": "EDNSクライアントサブネットを有効にする", "edns_cs_desc": "アップストリームリクエストにEDNSクライアントサブネットオプション(ECS)を追加し、クライアントから送信された値をクエリログに記録します。", + "edns_use_custom_ip": "EDNSにカスタムIPを使用する", + "edns_use_custom_ip_desc": "EDNS に対してカスタム IP の使用を許可します。", "rate_limit_desc": "一つのクライアントに対して許可される1秒あたりのリクエスト数(「0」に設定すると、制限なしになります)", "blocking_ipv4_desc": "ブロックされたAリクエストに対して応答されるIPアドレス", "blocking_ipv6_desc": "ブロックされたAAAAリクエストに対して応答されるIPアドレス", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "統計の保持を変更してもよろしいですか? 期間を短くすると、一部のデータが失われます", "statistics_cleared": "統計の消去に成功しました", "statistics_enable": "統計を有効にする", + "ignore_domains": "無視するドメイン(それぞれ改行で区切ってください)", + "ignore_domains_title": "無視するドメイン", + "ignore_domains_desc_stats": "これらのドメインへのクエリは統計に書き込まれません。", + "ignore_domains_desc_query": "これらのドメインへのクエリはクエリログに書き込まれません。", "interval_hours": "{{count}}時間", "interval_hours_plural": "{{count}}時間", "filters_configuration": "フィルタ設定", @@ -642,5 +649,24 @@ "anonymizer_notification": "【<0>注意】IPの匿名化が有効になっています。 <1>一般設定で無効にできます。", "confirm_dns_cache_clear": "DNS キャッシュをクリアしてもよろしいですか?", "cache_cleared": "DNSキャッシュのクリア完了です。", - "clear_cache": "キャッシュをクリアする" + "clear_cache": "キャッシュをクリアする", + "make_static": "静的(static)にする", + "theme_auto_desc": "自動(デバイスの配色に合わせる)", + "theme_dark_desc": "ダークテーマ", + "theme_light_desc": "ライトテーマ", + "disable_for_seconds": "{{count}}秒間", + "disable_for_seconds_plural": "{{count}}秒間", + "disable_for_minutes": "{{count}}分間", + "disable_for_minutes_plural": "{{count}}分間", + "disable_for_hours": "{{count}}時間", + "disable_for_hours_plural": "{{count}}時間", + "disable_until_tomorrow": "明日まで", + "disable_notify_for_seconds": "保護を {{count}} 秒間無効にする", + "disable_notify_for_seconds_plural": "保護を {{count}} 秒間無効にする", + "disable_notify_for_minutes": "保護を {{count}} 分間無効にする", + "disable_notify_for_minutes_plural": "保護を {{count}} 分間無効にする", + "disable_notify_for_hours": "保護を {{count}} 時間無効にする", + "disable_notify_for_hours_plural": "保護を {{count}} 時間無効にする", + "disable_notify_until_tomorrow": "明日まで保護を無効にする", + "enable_protection_timer": "保護は後 {{time}} で有効になります" } diff --git a/client/src/__locales/ko.json b/client/src/__locales/ko.json index 9847db95..cf0028e4 100644 --- a/client/src/__locales/ko.json +++ b/client/src/__locales/ko.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "자녀 보호 활성화됨", "disabled_safe_search_toast": "세이프서치 비활성화됨", "enabled_save_search_toast": "세이프서치 활성화됨", + "updated_save_search_toast": "세이프서치 설정 업데이트됨", "enabled_table_header": "활성화됨", "name_table_header": "이름", "list_url_table_header": "리스트 URL", @@ -290,6 +291,8 @@ "rate_limit": "한도 제한", "edns_enable": "EDNS 클라이언트 서브넷 활성화", "edns_cs_desc": "업스트림 요청에 EDNS 클라이언트 서브넷 옵션(ECS)을 추가하고 쿼리 로그에 클라이언트가 보낸 값을 기록합니다.", + "edns_use_custom_ip": "EDNS에 사용자 지정 IP 사용", + "edns_use_custom_ip_desc": "EDNS에 사용자 지정 IP 사용하도록 허용합니다.", "rate_limit_desc": "단일 클라이언트에서 허용 가능한 초 당 요청 생성 숫자 (0: 무제한)", "blocking_ipv4_desc": "차단된 A 요청에 대해서 반환할 IP 주소", "blocking_ipv6_desc": "차단된 AAAA 요청에 대해서 반환할 IP 주소", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "정말로 통계 저장 기간을 변경하시겠습니까? 저장 주기를 낮출 경우, 일부 데이터가 손실됩니다", "statistics_cleared": "통계를 성공적으로 초기화했습니다.", "statistics_enable": "통계 활성화", + "ignore_domains": "무시된 도메인(줄 바꿈으로 구분)", + "ignore_domains_title": "무시된 도메인", + "ignore_domains_desc_stats": "이러한 도메인에 대한 쿼리는 통계에 기록되지 않습니다.", + "ignore_domains_desc_query": "이러한 도메인에 대한 쿼리는 쿼리 로그에 기록되지 않습니다.", "interval_hours": "{{count}} 시간", "interval_hours_plural": "{{count}} 시간", "filters_configuration": "필터 구성", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>참고: IP 익명화가 활성화되었습니다. <1>일반 설정에서 비활성화할 수 있습니다.", "confirm_dns_cache_clear": "정말로 DNS 캐시를 지우시겠습니까?", "cache_cleared": "DNS 캐시를 성공적으로 지웠습니다", - "clear_cache": "캐시 지우기" + "clear_cache": "캐시 지우기", + "make_static": "정적으로 만들기", + "theme_auto_desc": "자동(기기의 색 구성표에 따라 설정)", + "theme_dark_desc": "다크 테마", + "theme_light_desc": "라이트 테마", + "disable_for_seconds": "{{count}}초", + "disable_for_seconds_plural": "{{count}}초", + "disable_for_minutes": "{{count}}분", + "disable_for_minutes_plural": "{{count}}분간", + "disable_for_hours": "{{count}}시간", + "disable_for_hours_plural": "{{count}}시간", + "disable_until_tomorrow": "내일까지", + "disable_notify_for_seconds": "{{count}}초 동안 보호 기능 비활성화", + "disable_notify_for_seconds_plural": "{{count}}초 동안 보호 기능 비활성화", + "disable_notify_for_minutes": "{{count}}분 동안 보호 기능 비활성화", + "disable_notify_for_minutes_plural": "{{count}}분 동안 보호 기능 비활성화", + "disable_notify_for_hours": "{{count}}시간 동안 보호 기능 비활성화", + "disable_notify_for_hours_plural": "{{count}}시간 동안 보호 기능 비활성화", + "disable_notify_until_tomorrow": "내일까지 보호 기능 비활성화", + "enable_protection_timer": "{{time}}에 보호 기능이 활성화됩니다." } diff --git a/client/src/__locales/nl.json b/client/src/__locales/nl.json index 9db3884f..474d9ad0 100644 --- a/client/src/__locales/nl.json +++ b/client/src/__locales/nl.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "Ingeschakeld Ouderlijk toezicht", "disabled_safe_search_toast": "Uitgeschakeld Veilig zoeken", "enabled_save_search_toast": "Ingeschakeld Veilig zoeken", + "updated_save_search_toast": "Safe Search-instellingen bijgewerkt", "enabled_table_header": "Ingeschakeld", "name_table_header": "Naam", "list_url_table_header": "URL lijst", @@ -290,6 +291,8 @@ "rate_limit": "Ratio limiet", "edns_enable": "EDNS client subnet inschakelen", "edns_cs_desc": "De EDNS Client Subnet-optie (ECS) toevoegen aan upstream-verzoeken en de waarden die door de clients zijn verzonden registreren in het querylogboek.", + "edns_use_custom_ip": "Aangepast IP-adres gebruiken voor EDNS", + "edns_use_custom_ip_desc": "Toestaan om aangepast IP-adres voor EDNS te gebruiken", "rate_limit_desc": "Het aantal verzoeken per seconde toegelaten per toestel. 0 betekent onbeperkt.", "blocking_ipv4_desc": "IP-adres dat moet worden teruggegeven voor een geblokkeerd A-verzoek", "blocking_ipv6_desc": "IP-adres dat moet worden teruggegeven voor een geblokkeerd A-verzoek", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "Weet u zeker dat u de bewaartermijn van de statistieken wilt wijzigen? Als u de intervalwaarde verlaagt, gaan sommige gegevens verloren", "statistics_cleared": "Statistieken succesvol gewist", "statistics_enable": "Statistieken inschakelen", + "ignore_domains": "Genegeerde domeinen (gescheiden door nieuwe regel)", + "ignore_domains_title": "Genegeerde domeinen", + "ignore_domains_desc_stats": "Zoekopdrachten voor deze domeinen worden niet naar de statistieken geschreven", + "ignore_domains_desc_query": "Zoekopdrachten voor deze domeinen worden niet naar het zoeklogboek geschreven", "interval_hours": "{{count}} uur", "interval_hours_plural": "{{count}} uren", "filters_configuration": "Filters instellingen", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>Opmerking: IP-anonimisering is ingeschakeld. Je kunt het uitschakelen in <1>Algemene instellingen.", "confirm_dns_cache_clear": "Weet je zeker dat je de DNS-cache wilt wissen?", "cache_cleared": "DNS-cache succesvol gewist", - "clear_cache": "Cache wissen" + "clear_cache": "Cache wissen", + "make_static": "Statisch maken", + "theme_auto_desc": "Automatisch (op basis van het kleurenschema van jouw apparaat)", + "theme_dark_desc": "Donker thema", + "theme_light_desc": "Licht thema", + "disable_for_seconds": "Voor {{count}} seconde", + "disable_for_seconds_plural": "Voor {{count}} seconden", + "disable_for_minutes": "Voor {{count}} minuut", + "disable_for_minutes_plural": "Voor {{count}} minuten", + "disable_for_hours": "Voor {{count}} uur", + "disable_for_hours_plural": "Voor {{count}} uren", + "disable_until_tomorrow": "Tot morgen", + "disable_notify_for_seconds": "Beveiliging uitschakelen voor {{count}} seconde", + "disable_notify_for_seconds_plural": "Beveiliging uitschakelen voor {{count}} seconden", + "disable_notify_for_minutes": "Beveiliging uitschakelen voor {{count}} minuut", + "disable_notify_for_minutes_plural": "Beveiliging uitschakelen voor {{count}} minuten", + "disable_notify_for_hours": "Beveiliging uitschakelen voor {{count}} uur", + "disable_notify_for_hours_plural": "Beveiliging uitschakelen voor {{count}} uren", + "disable_notify_until_tomorrow": "Beveiliging uitschakelen tot morgen", + "enable_protection_timer": "Bescherming wordt ingeschakeld over {{time}}" } diff --git a/client/src/__locales/pt-br.json b/client/src/__locales/pt-br.json index c7af3cc6..7e595612 100644 --- a/client/src/__locales/pt-br.json +++ b/client/src/__locales/pt-br.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "Controle parental ativado", "disabled_safe_search_toast": "Pesquisa segura desativada", "enabled_save_search_toast": "Pesquisa segura ativada", + "updated_save_search_toast": "Configurações de Pesquisa Segura atualizadas", "enabled_table_header": "Ativado", "name_table_header": "Nome", "list_url_table_header": "URL da lista", @@ -290,6 +291,8 @@ "rate_limit": "Taxa limite", "edns_enable": "Ativar a sub-rede do cliente EDNS", "edns_cs_desc": "Adicione a opção de sub-rede de cliente EDNS (ECS) às solicitações de servidor DNS primário e registre os valores enviados pelos clientes no registro de consulta.", + "edns_use_custom_ip": "Usar IP personalizado para EDNS", + "edns_use_custom_ip_desc": "Permitir o uso de IP personalizado para EDNS", "rate_limit_desc": "O número de solicitações por segundo permitidas por cliente. Definir como 0 significa que não há limite.", "blocking_ipv4_desc": "Endereço de IP a ser retornado para uma solicitação bloqueada", "blocking_ipv6_desc": "Endereço de IP a ser retornado para uma solicitação AAAA bloqueada", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "Você tem certeza que quer alterar o arquivamento das estatísticas? Se diminuir o valor do intervalo, alguns dados serão perdidos", "statistics_cleared": "As estatísticas foram limpas com sucesso", "statistics_enable": "Ativar estatísticas", + "ignore_domains": "Domínios ignorados (separados por nova linha)", + "ignore_domains_title": "Domínios ignorados", + "ignore_domains_desc_stats": "As consultas para esses domínios não são gravadas nas estatísticas", + "ignore_domains_desc_query": "As consultas para esses domínios não são gravadas no log de consulta", "interval_hours": "{{count}} hora", "interval_hours_plural": "{{count}} horas", "filters_configuration": "Configuração de filtros", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>Observação: A anonimização de IP está ativada. Você pode desativá-lo em <1>Configurações gerais.", "confirm_dns_cache_clear": "Tem certeza de que deseja limpar o cache DNS?", "cache_cleared": "Cache DNS limpo com sucesso", - "clear_cache": "Limpar cache" + "clear_cache": "Limpar cache", + "make_static": "Tornar estático", + "theme_auto_desc": "Automático (com base no esquema de cores do seu dispositivo)", + "theme_dark_desc": "Tema escuro", + "theme_light_desc": "Tema claro", + "disable_for_seconds": "Por {{count}} segundo", + "disable_for_seconds_plural": "Por {{count}} segundos", + "disable_for_minutes": "Por {{count}} minuto", + "disable_for_minutes_plural": "Por {{count}} minutos", + "disable_for_hours": "Por {{count}} hora", + "disable_for_hours_plural": "Por {{count}} horas", + "disable_until_tomorrow": "Até amanhã", + "disable_notify_for_seconds": "Desativar proteção por {{count}} segundo", + "disable_notify_for_seconds_plural": "Desativar proteção por {{count}} segundos", + "disable_notify_for_minutes": "Desativar proteção por {{count}} minuto", + "disable_notify_for_minutes_plural": "Desativar proteção por {{count}} minutos", + "disable_notify_for_hours": "Desativar proteção por {{count}} hora", + "disable_notify_for_hours_plural": "Desativar proteção por {{count}} horas", + "disable_notify_until_tomorrow": "Desativar a proteção até amanhã", + "enable_protection_timer": "A proteção será ativada em {{time}}" } diff --git a/client/src/__locales/pt-pt.json b/client/src/__locales/pt-pt.json index b710fe3d..34574c3e 100644 --- a/client/src/__locales/pt-pt.json +++ b/client/src/__locales/pt-pt.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "Controlo parental ativado", "disabled_safe_search_toast": "Pesquisa segura desativada", "enabled_save_search_toast": "Pesquisa segura ativada", + "updated_save_search_toast": "Configurações de pesquisa segura actualizadas", "enabled_table_header": "Ativado", "name_table_header": "Nome", "list_url_table_header": "URL da lista", @@ -290,6 +291,8 @@ "rate_limit": "Limite de taxa", "edns_enable": "Ativar a sub-rede do cliente EDNS", "edns_cs_desc": "Adicione a opção de sub-rede de cliente EDNS (ECS) às solicitações de servidor DNS primário e registre os valores enviados pelos clientes no registo de consulta.", + "edns_use_custom_ip": "Usar IP personalizado para EDNS", + "edns_use_custom_ip_desc": "Permitir a utilização de IP personalizado para EDNS", "rate_limit_desc": "O número de solicitações por segundo permitido por cliente. Configurando para 0 significa sem limite.", "blocking_ipv4_desc": "Endereço IP a ser devolvido para uma solicitação A bloqueada", "blocking_ipv6_desc": "Endereço IP a ser devolvido para uma solicitação AAAA bloqueada", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "Tem a certeza que quer alterar a retenção de estatísticas? Se diminuir o valor do intervalo, alguns dados serão perdidos", "statistics_cleared": "As estatísticas foram apagadas com sucesso", "statistics_enable": "Ativar estatísticas", + "ignore_domains": "Domínios ignorados (separados por nova linha)", + "ignore_domains_title": "Domínios ignorados", + "ignore_domains_desc_stats": "As consultas para estes domínios não aparecem nas estatísticas", + "ignore_domains_desc_query": "As consultas para estes domínios nãoaparecem no registo de consultas", "interval_hours": "{{count}} hora", "interval_hours_plural": "{{count}} horas", "filters_configuration": "Definição dos filtros", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>Observação: A anonimização de IP está ativada. Você pode desativá-la em <1>Definições gerais.", "confirm_dns_cache_clear": "Tem certeza de que quer limpar a cache DNS?", "cache_cleared": "O cache DNS foi apagado com sucesso", - "clear_cache": "Limpar cache" + "clear_cache": "Limpar cache", + "make_static": "Tornar estático", + "theme_auto_desc": "Automático (com base no esquema de cores do seu dispositivo)", + "theme_dark_desc": "Tema escuro", + "theme_light_desc": "Tema claro", + "disable_for_seconds": "Por {{count}} segundo", + "disable_for_seconds_plural": "Por {{count}} segundos", + "disable_for_minutes": "Por {{count}} minuto", + "disable_for_minutes_plural": "Por {{count}} minutos", + "disable_for_hours": "Por {{count}} hora", + "disable_for_hours_plural": "Por {{count}} horas", + "disable_until_tomorrow": "Até amanhã", + "disable_notify_for_seconds": "Desativar proteção por {{count}} segundo", + "disable_notify_for_seconds_plural": "Desativar proteção por {{count}} segundos", + "disable_notify_for_minutes": "Desativar proteção por {{count}} minuto", + "disable_notify_for_minutes_plural": "Desativar proteção por {{count}} minutos", + "disable_notify_for_hours": "Desativar proteção por {{count}} hora", + "disable_notify_for_hours_plural": "Desativar proteção por {{count}} horas", + "disable_notify_until_tomorrow": "Desativar a proteção até amanhã", + "enable_protection_timer": "A proteção será habilitada em {{time}}" } diff --git a/client/src/__locales/ru.json b/client/src/__locales/ru.json index afe8c5cf..aa78f3ae 100644 --- a/client/src/__locales/ru.json +++ b/client/src/__locales/ru.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "Родительский контроль вкл.", "disabled_safe_search_toast": "Безопасный поиск выкл.", "enabled_save_search_toast": "Безопасный поиск вкл.", + "updated_save_search_toast": "Настройки безопасного поиска обновлены", "enabled_table_header": "Вкл.", "name_table_header": "Имя", "list_url_table_header": "URL-адрес списка", @@ -290,6 +291,8 @@ "rate_limit": "Rate limit", "edns_enable": "Включить отправку EDNS Client Subnet", "edns_cs_desc": "Добавлять опцию EDNS Client Subnet (ECS) к запросам к upstream-серверам, а также записывать присланные клиентами значения в журнал.", + "edns_use_custom_ip": "Использовать указанный IP для EDNS", + "edns_use_custom_ip_desc": "Разрешить использовать собственный IP для EDNS", "rate_limit_desc": "Ограничение на количество запросов в секунду для каждого клиента (0 — неограниченно).", "blocking_ipv4_desc": "IP-адрес, возвращаемый при блокировке A-запроса", "blocking_ipv6_desc": "IP-адрес, возвращаемый при блокировке AAAA-запроса", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "Вы уверены, что хотите изменить срок хранения статистики? При сокращении интервала данные могут быть утеряны", "statistics_cleared": "Статистика успешно очищена", "statistics_enable": "Включить статистику", + "ignore_domains": "Игнорируемые домены (построчно)", + "ignore_domains_title": "Игнорируемые домены", + "ignore_domains_desc_stats": "Запросы для этих доменов не записываются в статистику", + "ignore_domains_desc_query": "Запросы для этих доменов не записываются в журнал запросов", "interval_hours": "{{count}} час", "interval_hours_plural": "{{count}} часов", "filters_configuration": "Настройка фильтров", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>Внимание: включена анонимизация IP-адресов. Вы можете отключить её в разделе <1>Основные настройки.", "confirm_dns_cache_clear": "Вы уверены, что хотите очистить кеш DNS?", "cache_cleared": "Кеш DNS успешно очищен", - "clear_cache": "Очистить кеш" + "clear_cache": "Очистить кеш", + "make_static": "Сделать статической", + "theme_auto_desc": "Авто (на основе цветовой схемы вашего устройства)", + "theme_dark_desc": "Тёмная тема", + "theme_light_desc": "Светлая тема", + "disable_for_seconds": "На {{count}} секунд", + "disable_for_seconds_plural": "На {{count}} секунд", + "disable_for_minutes": "На {{count}} минуту", + "disable_for_minutes_plural": "На {{count}} минут", + "disable_for_hours": "На {{count}} час", + "disable_for_hours_plural": "На {{count}} часов", + "disable_until_tomorrow": "До завтра", + "disable_notify_for_seconds": "Отключить защиту на {{count}} секунд", + "disable_notify_for_seconds_plural": "Отключить защиту на {{count}} секунд", + "disable_notify_for_minutes": "Отключить защиту на {{count}} минуту", + "disable_notify_for_minutes_plural": "Отключить защиту на {{count}} минут", + "disable_notify_for_hours": "Отключить защиту на {{count}} час", + "disable_notify_for_hours_plural": "Отключить защиту на {{count}} часов", + "disable_notify_until_tomorrow": "Отключить защиту до завтра", + "enable_protection_timer": "Защита будет включена в {{time}}" } diff --git a/client/src/__locales/sk.json b/client/src/__locales/sk.json index de0076a4..d98a9f53 100644 --- a/client/src/__locales/sk.json +++ b/client/src/__locales/sk.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "Zapnutá Rodičovská kontrola", "disabled_safe_search_toast": "Vypnuté Bezpečné vyhľadávanie", "enabled_save_search_toast": "Zapnuté Bezpečné vyhľadávanie", + "updated_save_search_toast": "Nastavenia Bezpečného vyhľadávania boli aktualizované", "enabled_table_header": "Zapnuté", "name_table_header": "Meno", "list_url_table_header": "Zoznam URL adries", @@ -290,6 +291,8 @@ "rate_limit": "Rýchlostný limit", "edns_enable": "Povoliť klientsku podsiete EDNS", "edns_cs_desc": "Pridáva možnosť EDNS Client Subnet (ECS) do upstream požiadaviek a zapíše hodnoty odoslané klientmi do denníka dopytov.", + "edns_use_custom_ip": "Použiť vlastnú IP adresu pre EDNS", + "edns_use_custom_ip_desc": "Povoliť používanie vlastnej IP adresy pre EDNS", "rate_limit_desc": "Počet požiadaviek za sekundu, ktoré môže jeden klient vykonať. Nastavenie na hodnotu 0 znamená neobmedzene.", "blocking_ipv4_desc": "IP adresa, ktorá sa má vrátiť v prípade blokovanej žiadosti A", "blocking_ipv6_desc": "IP adresa, ktorá sa má vrátiť v prípade blokovanej žiadosti AAAA", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "Naozaj chcete zmeniť uchovávanie štatistík? Ak znížite hodnotu intervalu, niektoré údaje sa stratia", "statistics_cleared": "Štatistika bola úspešne vynulovaná", "statistics_enable": "Zapnúť štatistiku", + "ignore_domains": "Ignorované domény (oddelené novým riadkom)", + "ignore_domains_title": "Ignorované domény", + "ignore_domains_desc_stats": "Dopyty pre tieto domény sa nezapisujú do štatistík", + "ignore_domains_desc_query": "Dopyty pre tieto domény sa nezapisujú do denníka dopytov", "interval_hours": "{{count}} hodina", "interval_hours_plural": "{{count}} hodín", "filters_configuration": "Konfigurácia filtrov", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>Poznámka: Anonymizácia IP je zapnutá. Môžete ju vypnúť vo <1>Všeobecných nastaveniach.", "confirm_dns_cache_clear": "Naozaj chcete vymazať vyrovnávaciu pamäť DNS?", "cache_cleared": "Vyrovnávacia pamäť DNS bola úspešne vymazaná", - "clear_cache": "Vymazať vyrovnávaciu pamäť" + "clear_cache": "Vymazať vyrovnávaciu pamäť", + "make_static": "Vytvárať štatistiku", + "theme_auto_desc": "Automaticky (na základe farebnej schémy Vášho zariadenia)", + "theme_dark_desc": "Tmavá téma", + "theme_light_desc": "Svetlá téma", + "disable_for_seconds": "Na {{count}} sekundu", + "disable_for_seconds_plural": "Na {{count}} sekúnd", + "disable_for_minutes": "Na {{count}} minútu", + "disable_for_minutes_plural": "Na {{count}} minút", + "disable_for_hours": "Na {{count}} hodinu", + "disable_for_hours_plural": "Na {{count}} hodín", + "disable_until_tomorrow": "Do zajtra", + "disable_notify_for_seconds": "Vypnite ochranu na {{count}} sekundu", + "disable_notify_for_seconds_plural": "Vypnite ochranu na {{count}} sekúnd", + "disable_notify_for_minutes": "Vypnite ochranu na {{count}} minútu", + "disable_notify_for_minutes_plural": "Vypnite ochranu na {{count}} minút", + "disable_notify_for_hours": "Vypnite ochranu na {{count}} hodinu", + "disable_notify_for_hours_plural": "Vypnite ochranu na {{count}} hodín", + "disable_notify_until_tomorrow": "Vypnúť ochranu do zajtra", + "enable_protection_timer": "Ochrana bude zapnutá o {{time}}" } diff --git a/client/src/__locales/sl.json b/client/src/__locales/sl.json index e8f6635c..a46256c2 100644 --- a/client/src/__locales/sl.json +++ b/client/src/__locales/sl.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "Omogočen starševski nadzor", "disabled_safe_search_toast": "Onemogočeno Varno iskanje", "enabled_save_search_toast": "Omogočeno Varno iskanje", + "updated_save_search_toast": "Nastavitve varnega iskanja so posodobljene", "enabled_table_header": "Omogočeno", "name_table_header": "Ime", "list_url_table_header": "Seznam URL naslovov", @@ -290,6 +291,8 @@ "rate_limit": "Omejitev hitrosti", "edns_enable": "Omogoči odjemalsko podomrežje EDNS", "edns_cs_desc": "Dodaj možnost podomrežja odjemalca EDNS (ECS) zahtevam v gorvodnem toku in zabeleži vrednosti, ki jih pošljejo odjemalci, v dnevnik poizvedb.", + "edns_use_custom_ip": "Uporabi IP po meri za EDNS", + "edns_use_custom_ip_desc": "Dovoli uporabo naslova IP po meri za EDNS", "rate_limit_desc": "Dovoljeno število zahtev na sekundo na odjemalca. Nastavitev na 0 pomeni brez omejitve.", "blocking_ipv4_desc": "IP naslov, ki mora biti vrnjen za onemogočeno zahtevo A", "blocking_ipv6_desc": "IP naslov, ki mora biti vrnjen za onemogočeno zahtevo AAAA", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "Ali ste prepričani, da želite spremeniti zadrževanje statistike? Če zmanjšate vrednost intervala, bodo nekateri podatki izgubljeni", "statistics_cleared": "Statistika je bila uspešno počiščena", "statistics_enable": "Omogoči statistiko", + "ignore_domains": "Prezrte domene (ločene z novo vrstico)", + "ignore_domains_title": "Prezrte domene", + "ignore_domains_desc_stats": "Poizvedbe za te domene niso zapisane v statistiko", + "ignore_domains_desc_query": "Poizvedbe za te domene niso zapisane v dnevnik poizvedb", "interval_hours": "{{count}} ur", "interval_hours_plural": "{{count}} ur", "filters_configuration": "Nastavitve filtrov", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>Opomba: Anonimizacija IP je omogočena. Onemogočite ga lahko v <1>Splošnih nastavitvah.", "confirm_dns_cache_clear": "Ali ste prepričani, da želite počistiti predpomnilnik DNS?", "cache_cleared": "Predpomnilnik DNS je bil uspešno počiščen", - "clear_cache": "Počisti predpomnilnik" + "clear_cache": "Počisti predpomnilnik", + "make_static": "Naredi statično", + "theme_auto_desc": "Samodejno (glede na barvno shemo vaše naprave)", + "theme_dark_desc": "Temna tema", + "theme_light_desc": "Svetla tema", + "disable_for_seconds": "Za {{count}} sekundo", + "disable_for_seconds_plural": "Za {{count}} sekund", + "disable_for_minutes": "Za {{count}} minuto", + "disable_for_minutes_plural": "Za {{count}} minut", + "disable_for_hours": "Za {{count}} uro", + "disable_for_hours_plural": "Za {{count}} ur", + "disable_until_tomorrow": "Do jutri", + "disable_notify_for_seconds": "Onemogoči zaščito za {{count}} sekundo", + "disable_notify_for_seconds_plural": "Onemogoči zaščito za {{count}} sekund", + "disable_notify_for_minutes": "Onemogoči zaščito za {{count}} minuto", + "disable_notify_for_minutes_plural": "Onemogoči zaščito za {{count}} minut", + "disable_notify_for_hours": "Onemogoči zaščito za {{count}} uro", + "disable_notify_for_hours_plural": "Onemogoči zaščito za {{count}} ur", + "disable_notify_until_tomorrow": "Onemogoči zaščito do jutri", + "enable_protection_timer": "Zaščita bo omogočena ob {{time}}" } diff --git a/client/src/__locales/sv.json b/client/src/__locales/sv.json index 94ca4570..cc004642 100644 --- a/client/src/__locales/sv.json +++ b/client/src/__locales/sv.json @@ -523,6 +523,7 @@ "statistics_retention_confirm": "Är du säker på att du vill ändra retentionstiden för statistik? Om du minskar intervallet kommer viss data att gå förlorad", "statistics_cleared": "Statistiken har rensats", "statistics_enable": "Aktivera statistik", + "ignore_domains_title": "Ignorerade domäner", "interval_hours": "{{count}} timme", "interval_hours_plural": "{{count}} timmar", "filters_configuration": "Filterinställningar", @@ -642,5 +643,14 @@ "anonymizer_notification": "<0>Observera: IP-anonymisering är aktiverad. Du kan inaktivera den i <1>Allmänna inställningar.", "confirm_dns_cache_clear": "Är du säker på att du vill rensa DNS-cache?", "cache_cleared": "DNS-cacheminnet har rensats", - "clear_cache": "Rensa cache" + "clear_cache": "Rensa cache", + "theme_dark_desc": "Mörkt tema", + "theme_light_desc": "Ljust tema", + "disable_for_seconds": "I {{count}} sekund", + "disable_for_seconds_plural": "I {{count}} sekunder", + "disable_for_minutes": "I {{count}} minut", + "disable_for_minutes_plural": "I {{count}} minuter", + "disable_for_hours": "I {{count}} timme", + "disable_for_hours_plural": "I {{count}} timmar", + "disable_until_tomorrow": "Tills imorgon" } diff --git a/client/src/__locales/tr.json b/client/src/__locales/tr.json index 70ab7a85..bb83a711 100644 --- a/client/src/__locales/tr.json +++ b/client/src/__locales/tr.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "Ebeveyn Denetimi etkinleştirildi", "disabled_safe_search_toast": "Güvenli Arama devre dışı bırakıldı", "enabled_save_search_toast": "Güvenli Arama etkinleştirildi", + "updated_save_search_toast": "Güvenli Arama ayarları güncellendi", "enabled_table_header": "Etkin", "name_table_header": "Ad", "list_url_table_header": "Liste URL'si", @@ -290,6 +291,8 @@ "rate_limit": "Sıklık limiti", "edns_enable": "EDNS istemci alt ağını etkinleştir", "edns_cs_desc": "Kaynak yönü isteklerine EDNS İstemci Alt Ağı seçeneğini (ECS) ekleyin ve istemciler tarafından gönderilen değerleri sorgu günlüğüne kaydedin.", + "edns_use_custom_ip": "EDNS için özel IP kullan", + "edns_use_custom_ip_desc": "EDNS için özel IP kullanımına izin ver", "rate_limit_desc": "İstemci başına izin verilen saniyedeki istek sayısı. 0 olarak ayarlamak, sınır olmadığı anlamına gelir.", "blocking_ipv4_desc": "Engellenen bir A isteği için geri döndürülecek IP adresi", "blocking_ipv6_desc": "Engellenen bir AAAA isteği için geri döndürülecek IP adresi", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "İstatistik saklama süresini değiştirmek istediğinizden emin misiniz? Aralık değerini azaltırsanız, bazı veriler kaybolacaktır", "statistics_cleared": "İstatistikler başarıyla temizlendi", "statistics_enable": "İstatistikleri etkinleştir", + "ignore_domains": "Yok sayılan alan adları (yeni satırla ayrılmış)", + "ignore_domains_title": "Yok sayılan alan adları", + "ignore_domains_desc_stats": "Bu alan adları için yapılan sorgular istatistiklere yazılmaz", + "ignore_domains_desc_query": "Bu alan adları için yapılan sorgular sorgu günlüğüne yazılmaz", "interval_hours": "{{count}} saat", "interval_hours_plural": "{{count}} saat", "filters_configuration": "Filtre yapılandırması", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>Not: IP anonimleştirme etkinleştirildi. Bunu <1>Genel ayarlardan devre dışı bırakabilirsiniz.", "confirm_dns_cache_clear": "DNS önbelleğini temizlemek istediğinizden emin misiniz?", "cache_cleared": "DNS önbelleği başarıyla temizlendi", - "clear_cache": "Önbelleği temizle" + "clear_cache": "Önbelleği temizle", + "make_static": "Statik yap", + "theme_auto_desc": "Otomatik (cihazınızın renk düzenine göre)", + "theme_dark_desc": "Koyu tema", + "theme_light_desc": "Açık tema", + "disable_for_seconds": "{{count}} saniye için", + "disable_for_seconds_plural": "{{count}} saniye için", + "disable_for_minutes": "{{count}} dakika için", + "disable_for_minutes_plural": "{{count}} dakika için", + "disable_for_hours": "{{count}} saat için", + "disable_for_hours_plural": "{{count}} saat için", + "disable_until_tomorrow": "Yarına kadar", + "disable_notify_for_seconds": "Korumayı {{count}} saniyeliğine devre dışı bırak", + "disable_notify_for_seconds_plural": "Korumayı {{count}} saniyeliğine devre dışı bırak", + "disable_notify_for_minutes": "Korumayı {{count}} dakiklığına devre dışı bırak", + "disable_notify_for_minutes_plural": "Korumayı {{count}} dakiklığına devre dışı bırak", + "disable_notify_for_hours": "Korumayı {{count}} saatliğine devre dışı bırak", + "disable_notify_for_hours_plural": "Korumayı {{count}} saatliğine devre dışı bırak", + "disable_notify_until_tomorrow": "Korumayı yarına kadar devre dışı bırak", + "enable_protection_timer": "Koruma {{time}} içinde etkinleştirilecektir" } diff --git a/client/src/__locales/zh-cn.json b/client/src/__locales/zh-cn.json index 3d417844..e0235dae 100644 --- a/client/src/__locales/zh-cn.json +++ b/client/src/__locales/zh-cn.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "家长控制已启用", "disabled_safe_search_toast": "安全搜索已禁用", "enabled_save_search_toast": "安全搜索已启用", + "updated_save_search_toast": "安全搜索设置更新成功", "enabled_table_header": "已启用", "name_table_header": "名称", "list_url_table_header": "清单网址", @@ -290,6 +291,8 @@ "rate_limit": "速度限制", "edns_enable": "启用 EDNS 客户端子网", "edns_cs_desc": "在上游请求中加入 EDNS 客户端子网(“EDNS Client Subnet”,即 ECS)选项,并在查询日志中记录客户端发送的数值。", + "edns_use_custom_ip": "为 EDNS 使用自定义 IP", + "edns_use_custom_ip_desc": "允许为 EDNS 使用自定义 IP", "rate_limit_desc": "每个客户端每秒钟查询次数的限制。设置为 0 意味着不限制。", "blocking_ipv4_desc": "拦截 A 记录请求返回的 IP 地址", "blocking_ipv6_desc": "拦截 AAAA 记录请求返回的 IP 地址", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "您确定要更改统计记录保留时间吗? 如果您减少间隔时间的值, 某些数据可能会丢失。", "statistics_cleared": "统计数据已成功清除", "statistics_enable": "启用统计数据", + "ignore_domains": "忽略的网域(以换行符分隔)", + "ignore_domains_title": "被忽略的网域", + "ignore_domains_desc_stats": "这些网域的查询不在统计信息", + "ignore_domains_desc_query": "这些网域的查询不在查询日志记录", "interval_hours": "{{count}} 小时", "interval_hours_plural": "{{count}} 小时", "filters_configuration": "过滤器配置", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>注意: IP 匿名化已启用。您可以在<1>常规设置中禁用它。", "confirm_dns_cache_clear": "您确定要清除 DNS 缓存吗?", "cache_cleared": "已成功清除 DNS 缓存", - "clear_cache": "清除缓存" + "clear_cache": "清除缓存", + "make_static": "静态化", + "theme_auto_desc": "自动(基于设备的配色方案)", + "theme_dark_desc": "暗黑主题", + "theme_light_desc": "浅色主题", + "disable_for_seconds": "{{count}} 秒", + "disable_for_seconds_plural": "{{count}} 秒", + "disable_for_minutes": "{{count}} 分钟", + "disable_for_minutes_plural": "{{count}} 分钟", + "disable_for_hours": "{{count}} 小时", + "disable_for_hours_plural": "{{count}} 小时", + "disable_until_tomorrow": "直到明天", + "disable_notify_for_seconds": "禁用保护 {{count}} 秒", + "disable_notify_for_seconds_plural": "禁用保护 {{count}} 秒", + "disable_notify_for_minutes": "禁用保护 {{count}} 分钟", + "disable_notify_for_minutes_plural": "禁用保护 {{count}} 分钟", + "disable_notify_for_hours": "禁用保护 {{count}} 小时", + "disable_notify_for_hours_plural": "禁用保护 {{count}} 小时", + "disable_notify_until_tomorrow": "禁用保护直到明天", + "enable_protection_timer": "保护将于 {{time}} 启用" } diff --git a/client/src/__locales/zh-tw.json b/client/src/__locales/zh-tw.json index 9701c49e..80b156ff 100644 --- a/client/src/__locales/zh-tw.json +++ b/client/src/__locales/zh-tw.json @@ -167,6 +167,7 @@ "enabled_parental_toast": "已啟用家長控制", "disabled_safe_search_toast": "已禁用安全搜尋", "enabled_save_search_toast": "已啟用安全搜尋", + "updated_save_search_toast": "安全搜尋設定更新成功", "enabled_table_header": "已啟用", "name_table_header": "名稱", "list_url_table_header": "清單網址", @@ -290,6 +291,8 @@ "rate_limit": "速率限制", "edns_enable": "啟用對於 DNS 的擴充機制(EDNS)用戶端子網路", "edns_cs_desc": "新增對於 DNS 的擴充機制(EDNS)用戶端子網路選項到上游的請求,並在查詢記錄中記錄由用戶端傳送的數值。", + "edns_use_custom_ip": "為 EDNS 使用自訂的 IP", + "edns_use_custom_ip_desc": "允許為 EDNS 使用自訂的 IP", "rate_limit_desc": "每個用戶端被允許的每秒請求之數量。設定它為 0 表示無限制。", "blocking_ipv4_desc": "要被返回給已封鎖的 A 請求之 IP 位址", "blocking_ipv6_desc": "要被返回給已封鎖的 AAAA 請求之 IP 位址", @@ -523,6 +526,10 @@ "statistics_retention_confirm": "您確定您想要更改統計資料保留嗎?如果您減少該間隔值,某些資料將被丟失", "statistics_cleared": "統計資料被成功地清除", "statistics_enable": "啟用統計資料", + "ignore_domains": "忽略的網域(以換行符分隔)", + "ignore_domains_title": "被忽略的網域", + "ignore_domains_desc_stats": "這些網域的查詢不在統計資料", + "ignore_domains_desc_query": "這些網域的查詢不在查詢記錄", "interval_hours": "{{count}} 小時", "interval_hours_plural": "{{count}} 小時", "filters_configuration": "過濾器配置", @@ -642,5 +649,24 @@ "anonymizer_notification": "<0>注意:IP 匿名化被啟用。您可在<1>一般設定中禁用它。", "confirm_dns_cache_clear": "您確定您想要清除 DNS 快取嗎?", "cache_cleared": "DNS 快取被成功地清除", - "clear_cache": "清除快取" + "clear_cache": "清除快取", + "make_static": "靜態化", + "theme_auto_desc": "自動(基於裝置的配色方案)", + "theme_dark_desc": "深色主題", + "theme_light_desc": "淺色主題", + "disable_for_seconds": "{{count}} 秒", + "disable_for_seconds_plural": "{{count}} 秒", + "disable_for_minutes": "{{count}} 分鐘", + "disable_for_minutes_plural": "{{count}} 分鐘", + "disable_for_hours": "{{count}} 小時", + "disable_for_hours_plural": "{{count}} 小時", + "disable_until_tomorrow": "直到明天", + "disable_notify_for_seconds": "計 {{count}} 秒禁用防護", + "disable_notify_for_seconds_plural": "計 {{count}} 秒禁用防護", + "disable_notify_for_minutes": "計 {{count}} 分鐘禁用防護", + "disable_notify_for_minutes_plural": "計 {{count}} 分鐘禁用防護", + "disable_notify_for_hours": "計 {{count}} 小時禁用防護", + "disable_notify_for_hours_plural": "計 {{count}} 小時禁用防護", + "disable_notify_until_tomorrow": "禁用防護直到明天", + "enable_protection_timer": "防護將於 {{time}} 被啟用" } diff --git a/client/src/actions/encryption.js b/client/src/actions/encryption.js index 5db97607..7ace1d2f 100644 --- a/client/src/actions/encryption.js +++ b/client/src/actions/encryption.js @@ -49,6 +49,9 @@ export const setTlsConfig = (config) => async (dispatch, getState) => { const dnsStatus = await apiClient.getGlobalStatus(); if (dnsStatus) { + if (dnsStatus.protection_disabled_duration === 0) { + dnsStatus.protection_disabled_duration = null; + } dispatch(dnsStatusSuccess(dnsStatus)); } diff --git a/client/src/actions/index.js b/client/src/actions/index.js index 2780c94d..5d96b045 100644 --- a/client/src/actions/index.js +++ b/client/src/actions/index.js @@ -6,7 +6,14 @@ import endsWith from 'lodash/endsWith'; import escapeRegExp from 'lodash/escapeRegExp'; import React from 'react'; import { compose } from 'redux'; -import { splitByNewLine, sortClients, filterOutComments } from '../helpers/helpers'; +import { + splitByNewLine, + sortClients, + filterOutComments, + msToSeconds, + msToMinutes, + msToHours, +} from '../helpers/helpers'; import { BLOCK_ACTIONS, CHECK_TIMEOUT, @@ -14,6 +21,7 @@ import { SETTINGS_NAMES, FORM_NAME, MANUAL_UPDATE_LINK, + DISABLE_PROTECTION_TIMINGS, } from '../helpers/constants'; import { areEqualVersions } from '../helpers/version'; import { getTlsStatus } from './encryption'; @@ -24,6 +32,12 @@ import { getFilteringStatus, setRules } from './filtering'; export const toggleSettingStatus = createAction('SETTING_STATUS_TOGGLE'); export const showSettingsFailure = createAction('SETTINGS_FAILURE_SHOW'); +/** + * + * @param {*} settingKey = SETTINGS_NAMES + * @param {*} status: boolean | SafeSearchConfig + * @returns + */ export const toggleSetting = (settingKey, status) => async (dispatch) => { let successMessage = ''; try { @@ -49,14 +63,9 @@ export const toggleSetting = (settingKey, status) => async (dispatch) => { dispatch(toggleSettingStatus({ settingKey })); break; case SETTINGS_NAMES.safesearch: - if (status) { - successMessage = 'disabled_safe_search_toast'; - await apiClient.disableSafesearch(); - } else { - successMessage = 'enabled_save_search_toast'; - await apiClient.enableSafesearch(); - } - dispatch(toggleSettingStatus({ settingKey })); + successMessage = 'updated_save_search_toast'; + await apiClient.updateSafesearch(status); + dispatch(toggleSettingStatus({ settingKey, value: status })); break; default: break; @@ -71,7 +80,9 @@ export const initSettingsRequest = createAction('SETTINGS_INIT_REQUEST'); export const initSettingsFailure = createAction('SETTINGS_INIT_FAILURE'); export const initSettingsSuccess = createAction('SETTINGS_INIT_SUCCESS'); -export const initSettings = (settingsList) => async (dispatch) => { +export const initSettings = (settingsList = { + safebrowsing: {}, parental: {}, +}) => async (dispatch) => { dispatch(initSettingsRequest()); try { const safebrowsingStatus = await apiClient.getSafebrowsingStatus(); @@ -80,7 +91,6 @@ export const initSettings = (settingsList) => async (dispatch) => { const { safebrowsing, parental, - safesearch, } = settingsList; const newSettingsList = { safebrowsing: { @@ -92,8 +102,7 @@ export const initSettings = (settingsList) => async (dispatch) => { enabled: parentalStatus.enabled, }, safesearch: { - ...safesearch, - enabled: safesearchStatus.enabled, + ...safesearchStatus, }, }; dispatch(initSettingsSuccess({ settingsList: newSettingsList })); @@ -107,19 +116,54 @@ export const toggleProtectionRequest = createAction('TOGGLE_PROTECTION_REQUEST') export const toggleProtectionFailure = createAction('TOGGLE_PROTECTION_FAILURE'); export const toggleProtectionSuccess = createAction('TOGGLE_PROTECTION_SUCCESS'); -export const toggleProtection = (status) => async (dispatch) => { +const getDisabledMessage = (time) => { + switch (time) { + case DISABLE_PROTECTION_TIMINGS.HALF_MINUTE: + return i18next.t( + 'disable_notify_for_seconds', + { count: msToSeconds(DISABLE_PROTECTION_TIMINGS.HALF_MINUTE) }, + ); + case DISABLE_PROTECTION_TIMINGS.MINUTE: + return i18next.t( + 'disable_notify_for_minutes', + { count: msToMinutes(DISABLE_PROTECTION_TIMINGS.MINUTE) }, + ); + case DISABLE_PROTECTION_TIMINGS.TEN_MINUTES: + return i18next.t( + 'disable_notify_for_minutes', + { count: msToMinutes(DISABLE_PROTECTION_TIMINGS.TEN_MINUTES) }, + ); + case DISABLE_PROTECTION_TIMINGS.HOUR: + return i18next.t( + 'disable_notify_for_hours', + { count: msToHours(DISABLE_PROTECTION_TIMINGS.HOUR) }, + ); + case DISABLE_PROTECTION_TIMINGS.TOMORROW: + return i18next.t('disable_notify_until_tomorrow'); + default: + return 'disabled_protection'; + } +}; + +export const toggleProtection = (status, time = null) => async (dispatch) => { dispatch(toggleProtectionRequest()); try { - const successMessage = status ? 'disabled_protection' : 'enabled_protection'; - await apiClient.setDnsConfig({ protection_enabled: !status }); + const successMessage = status ? getDisabledMessage(time) : 'enabled_protection'; + await apiClient.setProtection({ enabled: !status, duration: time }); dispatch(addSuccessToast(successMessage)); - dispatch(toggleProtectionSuccess()); + dispatch(toggleProtectionSuccess({ disabledDuration: time })); } catch (error) { dispatch(addErrorToast({ error })); dispatch(toggleProtectionFailure()); } }; +export const setDisableDurationTime = createAction('SET_DISABLED_DURATION_TIME'); + +export const setProtectionTimerTime = (updatedTime) => async (dispatch) => { + dispatch(setDisableDurationTime({ timeToEnableProtection: updatedTime })); +}; + export const getVersionRequest = createAction('GET_VERSION_REQUEST'); export const getVersionFailure = createAction('GET_VERSION_FAILURE'); export const getVersionSuccess = createAction('GET_VERSION_SUCCESS'); @@ -272,6 +316,9 @@ export const getDnsStatus = () => async (dispatch) => { const handleRequestSuccess = (response) => { const dnsStatus = response.data; + if (dnsStatus.protection_disabled_duration === 0) { + dnsStatus.protection_disabled_duration = null; + } const { running } = dnsStatus; const runningStatus = dnsStatus && running; if (runningStatus === true) { diff --git a/client/src/actions/queryLogs.js b/client/src/actions/queryLogs.js index 99da2cb0..e07c6fae 100644 --- a/client/src/actions/queryLogs.js +++ b/client/src/actions/queryLogs.js @@ -177,7 +177,7 @@ export const getLogsConfigSuccess = createAction('GET_LOGS_CONFIG_SUCCESS'); export const getLogsConfig = () => async (dispatch) => { dispatch(getLogsConfigRequest()); try { - const data = await apiClient.getQueryLogInfo(); + const data = await apiClient.getQueryLogConfig(); dispatch(getLogsConfigSuccess(data)); } catch (error) { dispatch(addErrorToast({ error })); diff --git a/client/src/actions/stats.js b/client/src/actions/stats.js index d3948efa..0e5b416e 100644 --- a/client/src/actions/stats.js +++ b/client/src/actions/stats.js @@ -13,7 +13,7 @@ export const getStatsConfigSuccess = createAction('GET_STATS_CONFIG_SUCCESS'); export const getStatsConfig = () => async (dispatch) => { dispatch(getStatsConfigRequest()); try { - const data = await apiClient.getStatsInfo(); + const data = await apiClient.getStatsConfig(); dispatch(getStatsConfigSuccess(data)); } catch (error) { dispatch(addErrorToast({ error })); diff --git a/client/src/api/Api.js b/client/src/api/Api.js index d984bbb8..7ca33293 100644 --- a/client/src/api/Api.js +++ b/client/src/api/Api.js @@ -208,24 +208,40 @@ class Api { // Safesearch SAFESEARCH_STATUS = { path: 'safesearch/status', method: 'GET' }; - SAFESEARCH_ENABLE = { path: 'safesearch/enable', method: 'POST' }; - - SAFESEARCH_DISABLE = { path: 'safesearch/disable', method: 'POST' }; + SAFESEARCH_UPDATE = { path: 'safesearch/settings', method: 'PUT' }; getSafesearchStatus() { const { path, method } = this.SAFESEARCH_STATUS; return this.makeRequest(path, method); } - enableSafesearch() { - const { path, method } = this.SAFESEARCH_ENABLE; - return this.makeRequest(path, method); + /** + * interface SafeSearchConfig { + "enabled": boolean, + "bing": boolean, + "duckduckgo": boolean, + "google": boolean, + "pixabay": boolean, + "yandex": boolean, + "youtube": boolean + * } + * @param {*} data - SafeSearchConfig + * @returns 200 ok + */ + updateSafesearch(data) { + const { path, method } = this.SAFESEARCH_UPDATE; + return this.makeRequest(path, method, { data }); } - disableSafesearch() { - const { path, method } = this.SAFESEARCH_DISABLE; - return this.makeRequest(path, method); - } + // enableSafesearch() { + // const { path, method } = this.SAFESEARCH_ENABLE; + // return this.makeRequest(path, method); + // } + + // disableSafesearch() { + // const { path, method } = this.SAFESEARCH_DISABLE; + // return this.makeRequest(path, method); + // } // Language @@ -497,9 +513,9 @@ class Api { // Settings for statistics GET_STATS = { path: 'stats', method: 'GET' }; - STATS_INFO = { path: 'stats_info', method: 'GET' }; + GET_STATS_CONFIG = { path: 'stats/config', method: 'GET' }; - STATS_CONFIG = { path: 'stats_config', method: 'POST' }; + UPDATE_STATS_CONFIG = { path: 'stats/config/update', method: 'PUT' }; STATS_RESET = { path: 'stats_reset', method: 'POST' }; @@ -508,13 +524,13 @@ class Api { return this.makeRequest(path, method); } - getStatsInfo() { - const { path, method } = this.STATS_INFO; + getStatsConfig() { + const { path, method } = this.GET_STATS_CONFIG; return this.makeRequest(path, method); } setStatsConfig(data) { - const { path, method } = this.STATS_CONFIG; + const { path, method } = this.UPDATE_STATS_CONFIG; const config = { data, }; @@ -529,9 +545,9 @@ class Api { // Query log GET_QUERY_LOG = { path: 'querylog', method: 'GET' }; - QUERY_LOG_CONFIG = { path: 'querylog_config', method: 'POST' }; + UPDATE_QUERY_LOG_CONFIG = { path: 'querylog/config/update', method: 'PUT' }; - QUERY_LOG_INFO = { path: 'querylog_info', method: 'GET' }; + GET_QUERY_LOG_CONFIG = { path: 'querylog/config', method: 'GET' }; QUERY_LOG_CLEAR = { path: 'querylog_clear', method: 'POST' }; @@ -543,13 +559,13 @@ class Api { return this.makeRequest(url, method); } - getQueryLogInfo() { - const { path, method } = this.QUERY_LOG_INFO; + getQueryLogConfig() { + const { path, method } = this.GET_QUERY_LOG_CONFIG; return this.makeRequest(path, method); } setQueryLogConfig(data) { - const { path, method } = this.QUERY_LOG_CONFIG; + const { path, method } = this.UPDATE_QUERY_LOG_CONFIG; const config = { data, }; @@ -611,6 +627,15 @@ class Api { return this.makeRequest(path, method, config); } + SET_PROTECTION = { path: 'protection', method: 'POST' }; + + setProtection(data) { + const { enabled, duration } = data; + const { path, method } = this.SET_PROTECTION; + + return this.makeRequest(path, method, { data: { enabled, duration } }); + } + // Cache CLEAR_CACHE = { path: 'cache_clear', method: 'POST' }; diff --git a/client/src/components/App/index.js b/client/src/components/App/index.js index 819bb0c6..d59f985f 100644 --- a/client/src/components/App/index.js +++ b/client/src/components/App/index.js @@ -43,6 +43,7 @@ import DnsRewrites from '../../containers/DnsRewrites'; import CustomRules from '../../containers/CustomRules'; import Services from '../Filters/Services'; import Logs from '../Logs'; +import ProtectionTimer from '../ProtectionTimer'; const ROUTES = [ { @@ -164,8 +165,7 @@ const App = () => { } const colorSchemeMedia = window.matchMedia('(prefers-color-scheme: dark)'); - const prefersDark = colorSchemeMedia.matches; - setUITheme(prefersDark ? THEMES.dark : THEMES.light); + setUITheme(theme); if (colorSchemeMedia.addEventListener !== undefined) { colorSchemeMedia.addEventListener('change', (e) => { @@ -191,6 +191,7 @@ const App = () => { {!processingEncryption && }
+
{processing && } {!isCoreRunning &&
diff --git a/client/src/components/Dashboard/Dashboard.css b/client/src/components/Dashboard/Dashboard.css index 415a3f6b..765c9ed1 100644 --- a/client/src/components/Dashboard/Dashboard.css +++ b/client/src/components/Dashboard/Dashboard.css @@ -1,3 +1,9 @@ +.dashboard-protection-button.btn-gray { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-right-color: #a4a4a4; +} + .stats__table .popover__body { left: -10px; min-width: 270px; @@ -34,20 +40,11 @@ align-items: center; } -.dashboard-title__button { - margin: 0 0.5rem; -} - @media (max-width: 767.98px) { .page-title--dashboard { flex-direction: column; align-items: flex-start; } - - .dashboard-title__button { - margin: 0.5rem 0; - display: block; - } } .counters__row { diff --git a/client/src/components/Dashboard/index.js b/client/src/components/Dashboard/index.js index cc19acf0..54354979 100644 --- a/client/src/components/Dashboard/index.js +++ b/client/src/components/Dashboard/index.js @@ -9,18 +9,25 @@ import Counters from './Counters'; import Clients from './Clients'; import QueriedDomains from './QueriedDomains'; import BlockedDomains from './BlockedDomains'; -import { SETTINGS_URLS } from '../../helpers/constants'; +import { DISABLE_PROTECTION_TIMINGS, ONE_SECOND_IN_MS, SETTINGS_URLS } from '../../helpers/constants'; +import { + msToSeconds, + msToMinutes, + msToHours, + msToDays, +} from '../../helpers/helpers'; import PageTitle from '../ui/PageTitle'; import Loading from '../ui/Loading'; import './Dashboard.css'; +import Dropdown from '../ui/Dropdown'; const Dashboard = ({ getAccessList, getStats, getStatsConfig, dashboard, - dashboard: { protectionEnabled, processingProtection }, + dashboard: { protectionEnabled, processingProtection, protectionDisabledDuration }, toggleProtection, stats, access, @@ -36,20 +43,20 @@ const Dashboard = ({ useEffect(() => { getAllStats(); }, []); - const getSubtitle = () => { - if (stats.interval === 0) { + const ONE_DAY = 1; + const intervalInDays = msToDays(stats.interval); + + if (intervalInDays < ONE_DAY) { return t('stats_disabled_short'); } - return stats.interval === 1 + return intervalInDays === ONE_DAY ? t('for_last_24_hours') - : t('for_last_days', { count: stats.interval }); + : t('for_last_days', { count: msToDays(stats.interval) }); }; - const buttonText = protectionEnabled ? 'disable_protection' : 'enable_protection'; - - const buttonClass = classNames('btn btn-sm dashboard-title__button', { + const buttonClass = classNames('btn btn-sm dashboard-protection-button', { 'btn-gray': protectionEnabled, 'btn-success': !protectionEnabled, }); @@ -71,16 +78,87 @@ const Dashboard = ({ const subtitle = getSubtitle(); + const DISABLE_PROTECTION_ITEMS = [ + { + text: t('disable_for_seconds', { count: msToSeconds(DISABLE_PROTECTION_TIMINGS.HALF_MINUTE) }), + disableTime: DISABLE_PROTECTION_TIMINGS.HALF_MINUTE, + }, + { + text: t('disable_for_minutes', { count: msToMinutes(DISABLE_PROTECTION_TIMINGS.MINUTE) }), + disableTime: DISABLE_PROTECTION_TIMINGS.MINUTE, + }, + { + text: t('disable_for_minutes', { count: msToMinutes(DISABLE_PROTECTION_TIMINGS.TEN_MINUTES) }), + disableTime: DISABLE_PROTECTION_TIMINGS.TEN_MINUTES, + }, + { + text: t('disable_for_hours', { count: msToHours(DISABLE_PROTECTION_TIMINGS.HOUR) }), + disableTime: DISABLE_PROTECTION_TIMINGS.HOUR, + }, + { + text: t('disable_until_tomorrow'), + disableTime: DISABLE_PROTECTION_TIMINGS.TOMORROW, + }, + ]; + + const getDisableProtectionItems = () => ( + Object.values(DISABLE_PROTECTION_ITEMS) + .map((item, index) => ( +
{ + toggleProtection(protectionEnabled, item.disableTime - ONE_SECOND_IN_MS); + }} + > + {item.text} +
+ )) + ); + + const getRemaningTimeText = (milliseconds) => { + if (!milliseconds) { + return ''; + } + + const date = new Date(milliseconds); + const hh = date.getUTCHours(); + const mm = `0${date.getUTCMinutes()}`.slice(-2); + const ss = `0${date.getUTCSeconds()}`.slice(-2); + const formattedHH = `0${hh}`.slice(-2); + + return hh ? `${formattedHH}:${mm}:${ss}` : `${mm}:${ss}`; + }; + + const getProtectionBtnText = (status) => (status ? t('disable_protection') : t('enable_protection')); + return <> - +
+ + + {protectionEnabled && + {getDisableProtectionItems()} + } +
))} +
+ +
+
+ {Object.keys(safeSearchServices).map((searchKey) => ( +
+ +
+ ))} +
, }, block_services: { @@ -358,6 +380,7 @@ Form.propTypes = { processingUpdating: PropTypes.bool.isRequired, invalid: PropTypes.bool.isRequired, tagsOptions: PropTypes.array.isRequired, + initialValues: PropTypes.object, }; const selector = formValueSelector(FORM_NAME.CLIENT); diff --git a/client/src/components/Settings/Dhcp/Leases.js b/client/src/components/Settings/Dhcp/Leases.js index 35bb8233..96ca8852 100644 --- a/client/src/components/Settings/Dhcp/Leases.js +++ b/client/src/components/Settings/Dhcp/Leases.js @@ -1,9 +1,11 @@ import React, { Component } from 'react'; +import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import ReactTable from 'react-table'; import { Trans, withTranslation } from 'react-i18next'; import { LEASES_TABLE_DEFAULT_PAGE_SIZE } from '../../../helpers/constants'; import { sortIp } from '../../../helpers/helpers'; +import { toggleLeaseModal } from '../../../actions'; class Leases extends Component { cellWrap = ({ value }) => ( @@ -14,6 +16,30 @@ class Leases extends Component { ); + convertToStatic = (data) => () => { + const { dispatch } = this.props; + dispatch(toggleLeaseModal(data)); + } + + makeStatic = ({ row }) => { + const { t, disabledLeasesButton } = this.props; + return ( +
+ +
+ ); + } + render() { const { leases, t } = this.props; return ( @@ -39,8 +65,11 @@ class Leases extends Component { }, { Header: dhcp_table_expires, accessor: 'expires', - minWidth: 130, + minWidth: 220, Cell: this.cellWrap, + }, { + Header: actions_table_header, + Cell: this.makeStatic, }, ]} pageSize={LEASES_TABLE_DEFAULT_PAGE_SIZE} @@ -57,6 +86,8 @@ class Leases extends Component { Leases.propTypes = { leases: PropTypes.array, t: PropTypes.func, + dispatch: PropTypes.func, + disabledLeasesButton: PropTypes.bool, }; -export default withTranslation()(Leases); +export default withTranslation()(connect(() => ({}), (dispatch) => ({ dispatch }))(Leases)); diff --git a/client/src/components/Settings/Dhcp/StaticLeases/Form.js b/client/src/components/Settings/Dhcp/StaticLeases/Form.js index 0525f6a3..e26b4da5 100644 --- a/client/src/components/Settings/Dhcp/StaticLeases/Form.js +++ b/client/src/components/Settings/Dhcp/StaticLeases/Form.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Field, reduxForm } from 'redux-form'; import { Trans, useTranslation } from 'react-i18next'; -import { useDispatch } from 'react-redux'; +import { useDispatch, useSelector, shallowEqual } from 'react-redux'; import { renderInputField, normalizeMac } from '../../../../helpers/form'; import { @@ -25,6 +25,7 @@ const Form = ({ }) => { const { t } = useTranslation(); const dispatch = useDispatch(); + const dynamicLease = useSelector((store) => store.dhcp.leaseModalConfig, shallowEqual); const onClick = () => { reset(); @@ -87,7 +88,7 @@ const Form = ({ diff --git a/client/src/components/Settings/Dhcp/StaticLeases/Modal.js b/client/src/components/Settings/Dhcp/StaticLeases/Modal.js index 0baf487e..7a11cfce 100644 --- a/client/src/components/Settings/Dhcp/StaticLeases/Modal.js +++ b/client/src/components/Settings/Dhcp/StaticLeases/Modal.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Trans, withTranslation } from 'react-i18next'; import ReactModal from 'react-modal'; -import { useDispatch } from 'react-redux'; +import { shallowEqual, useDispatch, useSelector } from 'react-redux'; import Form from './Form'; import { toggleLeaseModal } from '../../../../actions'; @@ -18,6 +18,9 @@ const Modal = ({ const dispatch = useDispatch(); const toggleModal = () => dispatch(toggleLeaseModal()); + const leaseInitialData = useSelector( + (state) => state.dhcp.leaseModalConfig, shallowEqual, + ) || {}; return (
{ const inputtedIPv4values = dhcp?.values?.v4?.gateway_ip && dhcp?.values?.v4?.subnet_mask; const isEmptyConfig = !Object.values(dhcp?.values?.v4 ?? {}).some(Boolean); - const disabledLeasesButton = dhcp?.syncErrors || interfaces?.syncErrors - || !isInterfaceIncludesIpv4 || isEmptyConfig || processingConfig || !inputtedIPv4values; + const disabledLeasesButton = Boolean(dhcp?.syncErrors || interfaces?.syncErrors + || !isInterfaceIncludesIpv4 || isEmptyConfig || processingConfig || !inputtedIPv4values); const cidr = inputtedIPv4values ? `${dhcp?.values?.v4?.gateway_ip}/${subnetMaskToBitMask(dhcp?.values?.v4?.subnet_mask)}` : ''; return <> @@ -260,7 +260,7 @@ const Dhcp = () => { >
- +
} diff --git a/client/src/components/Settings/Dns/Config/Form.js b/client/src/components/Settings/Dns/Config/Form.js index a2dd2bf9..52d94741 100644 --- a/client/src/components/Settings/Dns/Config/Form.js +++ b/client/src/components/Settings/Dns/Config/Form.js @@ -13,15 +13,11 @@ import { validateIpv4, validateIpv6, validateRequiredValue, + validateIp, } from '../../../../helpers/validators'; import { BLOCKING_MODES, FORM_NAME, UINT32_RANGE } from '../../../../helpers/constants'; const checkboxes = [ - { - name: 'edns_cs_enabled', - placeholder: 'edns_enable', - subtitle: 'edns_cs_desc', - }, { name: 'dnssec_enabled', placeholder: 'dnssec_enable', @@ -66,6 +62,8 @@ const Form = ({ const { t } = useTranslation(); const { blocking_mode, + edns_cs_enabled, + edns_cs_use_custom, } = useSelector((state) => state.form[FORM_NAME.BLOCKING_MODE].values ?? {}, shallowEqual); return @@ -92,6 +90,39 @@ const Form = ({ /> +
+
+ +
+
+
+
+ +
+ + {edns_cs_use_custom && ()} + +
{checkboxes.map(({ name, placeholder, subtitle }) =>
{ blocking_ipv4, blocking_ipv6, edns_cs_enabled, + edns_cs_use_custom, + edns_cs_custom_ip, dnssec_enabled, disable_ipv6, processingSetConfig, @@ -39,6 +41,8 @@ const Config = () => { edns_cs_enabled, disable_ipv6, dnssec_enabled, + edns_cs_use_custom, + edns_cs_custom_ip, }} onSubmit={handleFormSubmit} processing={processingSetConfig} diff --git a/client/src/components/Settings/LogsConfig/Form.js b/client/src/components/Settings/LogsConfig/Form.js index 8db3f18d..b29b974e 100644 --- a/client/src/components/Settings/LogsConfig/Form.js +++ b/client/src/components/Settings/LogsConfig/Form.js @@ -4,18 +4,28 @@ import { Field, reduxForm } from 'redux-form'; import { Trans, withTranslation } from 'react-i18next'; import flow from 'lodash/flow'; -import { CheckboxField, renderRadioField, toFloatNumber } from '../../../helpers/form'; -import { FORM_NAME, QUERY_LOG_INTERVALS_DAYS } from '../../../helpers/constants'; +import { + CheckboxField, + renderRadioField, + toFloatNumber, + renderTextareaField, +} from '../../../helpers/form'; +import { + FORM_NAME, + QUERY_LOG_INTERVALS_DAYS, + HOUR, + DAY, +} from '../../../helpers/constants'; import '../FormButton.css'; const getIntervalTitle = (interval, t) => { switch (interval) { - case 0.25: + case 6 * HOUR: return t('interval_6_hour'); - case 1: + case DAY: return t('interval_24_hour'); default: - return t('interval_days', { count: interval }); + return t('interval_days', { count: interval / DAY }); } }; @@ -66,6 +76,22 @@ const Form = (props) => { {getIntervalFields(processing, t, toFloatNumber)}
+ +
+ ignore_domains_desc_query +
+
+ +