Compare commits
134 Commits
fixbug/mac
...
improve_na
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25a24bf38c | ||
|
|
5e492e8392 | ||
|
|
b25d911328 | ||
|
|
caf29fb982 | ||
|
|
32ef1eae84 | ||
|
|
b0fdbe6c4f | ||
|
|
dccfcde6f6 | ||
|
|
26ba520022 | ||
|
|
0f98fc955f | ||
|
|
2c1f3eaf3a | ||
|
|
867ad8ee3c | ||
|
|
f8f4d75cb7 | ||
|
|
b88ab8e432 | ||
|
|
13e680f6e1 | ||
|
|
8767f487b8 | ||
|
|
0cdd2ff826 | ||
|
|
c973b8868b | ||
|
|
53aa14a2ee | ||
|
|
b29b5962d2 | ||
|
|
441a2f6df6 | ||
|
|
fa64c8d68d | ||
|
|
48f6cf904e | ||
|
|
ae31bafeb9 | ||
|
|
14d67503a8 | ||
|
|
1029142b47 | ||
|
|
7670d9dace | ||
|
|
2266702a0b | ||
|
|
11d20974f0 | ||
|
|
a57e94e4f2 | ||
|
|
9620a24d6a | ||
|
|
62be292833 | ||
|
|
10e91b06f4 | ||
|
|
3a62f1f20b | ||
|
|
3021066180 | ||
|
|
378db1a9e5 | ||
|
|
906cf7b939 | ||
|
|
8bc31b60a1 | ||
|
|
149c9d12d3 | ||
|
|
b33b97802e | ||
|
|
367789bda2 | ||
|
|
d18f50a3e0 | ||
|
|
ef2ffce47a | ||
|
|
53f41408b8 | ||
|
|
d06924c59d | ||
|
|
5b9ba8c027 | ||
|
|
2db99715b1 | ||
|
|
882c288d92 | ||
|
|
ea39447708 | ||
|
|
3cc70790bd | ||
|
|
f331c11f51 | ||
|
|
39cbe6de28 | ||
|
|
9688a8e52d | ||
|
|
b2c429f74d | ||
|
|
6ea6ab1bd9 | ||
|
|
c5aa070bf4 | ||
|
|
d67201ede9 | ||
|
|
4323fb2063 | ||
|
|
6d5452b8ee | ||
|
|
569d63ef0f | ||
|
|
87d00116e1 | ||
|
|
ea910ba300 | ||
|
|
1c1e74d06f | ||
|
|
5dc16c06f1 | ||
|
|
f992252c6e | ||
|
|
4efaf20a1c | ||
|
|
9d96b1cd13 | ||
|
|
1d721ffb9a | ||
|
|
2130131a9d | ||
|
|
e0b091b474 | ||
|
|
c9205afbd4 | ||
|
|
09b1f322ba | ||
|
|
4d2d7e4071 | ||
|
|
c72d76aec7 | ||
|
|
50bd364f29 | ||
|
|
3eeab2f2e7 | ||
|
|
2987e03a86 | ||
|
|
392cacaabc | ||
|
|
51092e91cf | ||
|
|
d02a6dfb22 | ||
|
|
4e1862a802 | ||
|
|
53e766f6d3 | ||
|
|
341d6f569b | ||
|
|
a5abab8caf | ||
|
|
7df050371e | ||
|
|
65870ad5c9 | ||
|
|
940806a6fa | ||
|
|
0620b4536a | ||
|
|
d956be901d | ||
|
|
942805cca2 | ||
|
|
ed6fc27e52 | ||
|
|
416421cba7 | ||
|
|
45b8235a81 | ||
|
|
a92f706524 | ||
|
|
5e9202f6ac | ||
|
|
dc6c1cdf49 | ||
|
|
f020bdb6e8 | ||
|
|
88958c042f | ||
|
|
e4d21dc4d7 | ||
|
|
2e896ed34f | ||
|
|
163399816f | ||
|
|
3d7209ee7a | ||
|
|
42645a98f8 | ||
|
|
7c3d08d80e | ||
|
|
c77e01fb37 | ||
|
|
b6c59b08a1 | ||
|
|
766e1c92fc | ||
|
|
21755cbd54 | ||
|
|
dac45a9f7f | ||
|
|
db5d289edc | ||
|
|
c962211068 | ||
|
|
9cfa4c1389 | ||
|
|
2c9fa10b8b | ||
|
|
626b9e1e76 | ||
|
|
ada3f9a7fa | ||
|
|
063851445a | ||
|
|
852e90e317 | ||
|
|
89ac585e07 | ||
|
|
f3df9eb5f5 | ||
|
|
75f189e256 | ||
|
|
3c655d0051 | ||
|
|
b4f4ec4ac9 | ||
|
|
f189f7b6af | ||
|
|
78a4caa47e | ||
|
|
01e31b4b4d | ||
|
|
cecee3769e | ||
|
|
02bbcd3a31 | ||
|
|
8547de82ea | ||
|
|
aa871bd1c9 | ||
|
|
23806e1def | ||
|
|
31867993ce | ||
|
|
7b7a922d92 | ||
|
|
09bd958d8d | ||
|
|
576e2226fe | ||
|
|
1533270e4e |
39
.clang-format
Normal file
@@ -0,0 +1,39 @@
|
||||
BasedOnStyle: WebKit
|
||||
AccessModifierOffset: '-4'
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveMacros: 'true'
|
||||
AlignTrailingComments: 'true'
|
||||
AllowAllArgumentsOnNextLine: 'true'
|
||||
AllowAllParametersOfDeclarationOnNextLine: 'true'
|
||||
AllowShortBlocksOnASingleLine: 'false'
|
||||
AllowShortCaseLabelsOnASingleLine: 'true'
|
||||
AllowShortEnumsOnASingleLine: 'false'
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AlwaysBreakTemplateDeclarations: 'No'
|
||||
BreakBeforeBinaryOperators: NonAssignment
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: true
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
ColumnLimit: '120'
|
||||
CommentPragmas: '"^!|^:"'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: 'true'
|
||||
ConstructorInitializerIndentWidth: '4'
|
||||
ContinuationIndentWidth: '8'
|
||||
IndentPPDirectives: BeforeHash
|
||||
NamespaceIndentation: All
|
||||
PenaltyExcessCharacter: '10'
|
||||
PointerAlignment: Right
|
||||
SortIncludes: 'true'
|
||||
SpaceAfterTemplateKeyword: 'false'
|
||||
Standard: Auto
|
||||
20
.clang-format-ignore
Normal file
@@ -0,0 +1,20 @@
|
||||
/client/3rd
|
||||
/client/3rd-prebuild
|
||||
/client/android
|
||||
/client/cmake
|
||||
/client/core/serialization
|
||||
/client/daemon
|
||||
/client/fonts
|
||||
/client/images
|
||||
/client/ios
|
||||
/client/mozilla
|
||||
/client/platforms/dummy
|
||||
/client/platforms/linux
|
||||
/client/platforms/macos
|
||||
/client/platforms/windows
|
||||
/client/server_scripts
|
||||
/client/translations
|
||||
/deploy
|
||||
/docs
|
||||
/metadata
|
||||
/service/src
|
||||
89
.github/workflows/deploy.yml
vendored
@@ -217,7 +217,11 @@ jobs:
|
||||
export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/ios/bin"
|
||||
export QT_MACOS_ROOT_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos"
|
||||
export PATH=$PATH:~/go/bin
|
||||
sh deploy/build_ios.sh
|
||||
sh deploy/build_ios.sh | \
|
||||
sed -e '/-Xcc -DPROD_AGW_PUBLIC_KEY/,/-Xcc/ { /-Xcc/!d; }' -e '/-Xcc -DPROD_AGW_PUBLIC_KEY/d' | \
|
||||
sed -e '/-Xcc -DDEV_AGW_PUBLIC_KEY/,/-Xcc/ { /-Xcc/!d; }' -e '/-Xcc -DDEV_AGW_PUBLIC_KEY/d' | \
|
||||
sed -e '/-DPROD_AGW_PUBLIC_KEY/,/-D/ { /-D/!d; }' -e '/-DPROD_AGW_PUBLIC_KEY/d' | \
|
||||
sed -e '/-DDEV_AGW_PUBLIC_KEY/,/-D/ { /-D/!d; }' -e '/-DDEV_AGW_PUBLIC_KEY/d'
|
||||
env:
|
||||
IOS_TRUST_CERT_BASE64: ${{ secrets.IOS_TRUST_CERT_BASE64 }}
|
||||
IOS_SIGNING_CERT_BASE64: ${{ secrets.IOS_SIGNING_CERT_BASE64 }}
|
||||
@@ -256,7 +260,7 @@ jobs:
|
||||
- name: 'Setup xcode'
|
||||
uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: '14.3.1'
|
||||
xcode-version: '15.4.0'
|
||||
|
||||
- name: 'Install Qt'
|
||||
uses: jurplel/install-qt-action@v3
|
||||
@@ -306,70 +310,6 @@ jobs:
|
||||
path: deploy/build/client/AmneziaVPN.app
|
||||
retention-days: 7
|
||||
|
||||
# ------------------------------------------------------
|
||||
Build-MacOS-NE:
|
||||
runs-on: macos-latest
|
||||
|
||||
env:
|
||||
QT_VERSION: 6.4.3
|
||||
QIF_VERSION: 4.6
|
||||
QT_MIRROR: https://mirrors.ocf.berkeley.edu/qt/
|
||||
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
|
||||
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
|
||||
|
||||
steps:
|
||||
- name: 'Setup Xcode'
|
||||
uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: '14.3.1'
|
||||
|
||||
- name: 'Install desktop Qt'
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
host: 'mac'
|
||||
target: 'desktop'
|
||||
modules: 'qtremoteobjects qt5compat qtshadertools qtmultimedia'
|
||||
arch: 'clang_64'
|
||||
dir: ${{ runner.temp }}
|
||||
set-env: 'true'
|
||||
extra: '--base ${{ env.QT_MIRROR }}'
|
||||
- name: 'Install Qt Installer Framework ${{ env.QIF_VERSION }}'
|
||||
run: |
|
||||
mkdir -pv ${{ runner.temp }}/Qt/Tools/QtInstallerFramework
|
||||
wget https://qt.amzsvc.com/tools/ifw/${{ env.QIF_VERSION }}.zip
|
||||
unzip ${{ env.QIF_VERSION }}.zip -d ${{ runner.temp }}/Qt/Tools/QtInstallerFramework/
|
||||
- name: 'Install Go'
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22.1'
|
||||
cache: false
|
||||
|
||||
- name: 'Get sources'
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'true'
|
||||
fetch-depth: 10
|
||||
|
||||
- name: 'Install dependencies'
|
||||
run: pip install jsonschema jinja2
|
||||
|
||||
- name: 'Set execute permissions for deploy script'
|
||||
run: chmod +x deploy/build_macos_ne.sh
|
||||
|
||||
# - name: 'Build and deploy macOS NE'
|
||||
# run: |
|
||||
# export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos/bin"
|
||||
# export QIF_BIN_DIR="${{ runner.temp }}/Qt/Tools/QtInstallerFramework/${{ env.QIF_VERSION }}/bin"
|
||||
# export QT_MACOS_ROOT_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos"
|
||||
# bash deploy/build_macos_ne.sh
|
||||
# env:
|
||||
# APPSTORE_CONNECT_KEY_ID: ${{ secrets.APPSTORE_CONNECT_KEY_ID }}
|
||||
# APPSTORE_CONNECT_ISSUER_ID: ${{ secrets.APPSTORE_CONNECT_ISSUER_ID }}
|
||||
# APPSTORE_CONNECT_PRIVATE_KEY: ${{ secrets.APPSTORE_CONNECT_PRIVATE_KEY }}
|
||||
# MAC_TRUST_CERT_BASE64: ${{ secrets.IOS_TRUST_CERT_BASE64 }}
|
||||
# MAC_SIGNING_CERT_BASE64: ${{ secrets.IOS_SIGNING_CERT_BASE64 }}
|
||||
# MAC_SIGNING_CERT_PASSWORD: ${{ secrets.IOS_SIGNING_CERT_PASSWORD }}
|
||||
# ------------------------------------------------------
|
||||
|
||||
Build-Android:
|
||||
@@ -395,7 +335,8 @@ jobs:
|
||||
arch: 'linux_gcc_64'
|
||||
modules: ${{ env.QT_MODULES }}
|
||||
dir: ${{ runner.temp }}
|
||||
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
|
||||
py7zrversion: '==0.22.*'
|
||||
extra: '--base ${{ env.QT_MIRROR }}'
|
||||
|
||||
- name: 'Install android_x86_64 Qt'
|
||||
uses: jurplel/install-qt-action@v4
|
||||
@@ -406,7 +347,8 @@ jobs:
|
||||
arch: 'android_x86_64'
|
||||
modules: ${{ env.QT_MODULES }}
|
||||
dir: ${{ runner.temp }}
|
||||
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
|
||||
py7zrversion: '==0.22.*'
|
||||
extra: '--base ${{ env.QT_MIRROR }}'
|
||||
|
||||
- name: 'Install android_x86 Qt'
|
||||
uses: jurplel/install-qt-action@v4
|
||||
@@ -417,7 +359,8 @@ jobs:
|
||||
arch: 'android_x86'
|
||||
modules: ${{ env.QT_MODULES }}
|
||||
dir: ${{ runner.temp }}
|
||||
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
|
||||
py7zrversion: '==0.22.*'
|
||||
extra: '--base ${{ env.QT_MIRROR }}'
|
||||
|
||||
- name: 'Install android_armv7 Qt'
|
||||
uses: jurplel/install-qt-action@v4
|
||||
@@ -428,7 +371,8 @@ jobs:
|
||||
arch: 'android_armv7'
|
||||
modules: ${{ env.QT_MODULES }}
|
||||
dir: ${{ runner.temp }}
|
||||
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
|
||||
py7zrversion: '==0.22.*'
|
||||
extra: '--base ${{ env.QT_MIRROR }}'
|
||||
|
||||
- name: 'Install android_arm64_v8a Qt'
|
||||
uses: jurplel/install-qt-action@v4
|
||||
@@ -439,7 +383,8 @@ jobs:
|
||||
arch: 'android_arm64_v8a'
|
||||
modules: ${{ env.QT_MODULES }}
|
||||
dir: ${{ runner.temp }}
|
||||
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
|
||||
py7zrversion: '==0.22.*'
|
||||
extra: '--base ${{ env.QT_MIRROR }}'
|
||||
|
||||
- name: 'Grant execute permission for qt-cmake'
|
||||
shell: bash
|
||||
@@ -540,4 +485,4 @@ jobs:
|
||||
if: ${{ fromJSON(steps.pull_request.outputs.data)[0].number != '' }}
|
||||
run: |
|
||||
echo "Pull request:" >> $GITHUB_STEP_SUMMARY
|
||||
echo "[[#${{ fromJSON(steps.pull_request.outputs.data)[0].number }}] ${{ fromJSON(steps.pull_request.outputs.data)[0].title }}](${{ fromJSON(steps.pull_request.outputs.data)[0].html_url }})" >> $GITHUB_STEP_SUMMARY
|
||||
echo "[[#${{ fromJSON(steps.pull_request.outputs.data)[0].number }}] ${{ fromJSON(steps.pull_request.outputs.data)[0].title }}](${{ fromJSON(steps.pull_request.outputs.data)[0].html_url }})" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
2
.gitmodules
vendored
@@ -1,7 +1,6 @@
|
||||
[submodule "client/3rd/OpenVPNAdapter"]
|
||||
path = client/3rd/OpenVPNAdapter
|
||||
url = https://github.com/amnezia-vpn/OpenVPNAdapter.git
|
||||
branch = macos-dirty-build
|
||||
[submodule "client/3rd/qtkeychain"]
|
||||
path = client/3rd/qtkeychain
|
||||
url = https://github.com/frankosterfeld/qtkeychain.git
|
||||
@@ -11,7 +10,6 @@
|
||||
[submodule "client/3rd-prebuilt"]
|
||||
path = client/3rd-prebuilt
|
||||
url = https://github.com/amnezia-vpn/3rd-prebuilt
|
||||
branch = fixbug/mac-network-extension
|
||||
[submodule "client/3rd/amneziawg-apple"]
|
||||
path = client/3rd/amneziawg-apple
|
||||
url = https://github.com/amnezia-vpn/amneziawg-apple
|
||||
|
||||
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
|
||||
|
||||
set(PROJECT AmneziaVPN)
|
||||
|
||||
project(${PROJECT} VERSION 4.8.2.3
|
||||
project(${PROJECT} VERSION 4.8.3.0
|
||||
DESCRIPTION "AmneziaVPN"
|
||||
HOMEPAGE_URL "https://amnezia.org/"
|
||||
)
|
||||
@@ -11,7 +11,7 @@ string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
|
||||
set(RELEASE_DATE "${CURRENT_DATE}")
|
||||
|
||||
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
||||
set(APP_ANDROID_VERSION_CODE 2069)
|
||||
set(APP_ANDROID_VERSION_CODE 2072)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
set(MZ_PLATFORM_NAME "linux")
|
||||
@@ -31,13 +31,13 @@ set(QT_BUILD_TOOLS_WHEN_CROSS_COMPILING ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
if((APPLE AND NOT IOS) OR (DEFINED MACOS_NE AND MACOS_NE AND NOT IOS))
|
||||
if(APPLE AND NOT IOS)
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64")
|
||||
endif()
|
||||
|
||||
add_subdirectory(client)
|
||||
|
||||
if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
|
||||
if(NOT IOS AND NOT ANDROID)
|
||||
add_subdirectory(service)
|
||||
|
||||
include(${CMAKE_SOURCE_DIR}/deploy/installer/config.cmake)
|
||||
|
||||
30
README.md
@@ -1,24 +1,29 @@
|
||||
# Amnezia VPN
|
||||
## _The best client for self-hosted VPN_
|
||||
|
||||
### _The best client for self-hosted VPN_
|
||||
|
||||
|
||||
[](https://github.com/amnezia-vpn/amnezia-client/actions/workflows/deploy.yml?query=branch:dev)
|
||||
[](https://gitpod.io/#https://github.com/amnezia-vpn/amnezia-client)
|
||||
|
||||
Amnezia is an open-source VPN client, with a key feature that enables you to deploy your own VPN server on your server.
|
||||
### [English]([https://github.com/amnezia-vpn/amnezia-client/blob/dev/README_RU.md](https://github.com/amnezia-vpn/amnezia-client/tree/dev?tab=readme-ov-file#)) | [Русский](https://github.com/amnezia-vpn/amnezia-client/blob/dev/README_RU.md)
|
||||
|
||||

|
||||
|
||||
<br>
|
||||
[Amnezia](https://amnezia.org) is an open-source VPN client, with a key feature that enables you to deploy your own VPN server on your server.
|
||||
|
||||
<a href="https://amnezia.org/downloads"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/download.png" width="150" style="max-width: 100%;"></a>
|
||||
<a href="https://play.google.com/store/search?q=amnezia+vpn&c=apps"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/play.png" width="150" style="max-width: 100%;"></a>
|
||||
<a href="https://apps.apple.com/us/app/amneziavpn/id1600529900"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/apl.png" width="150" style="max-width: 100%;"></a>
|
||||
[](https://amnezia.org)
|
||||
|
||||
[Alternative download link (mirror)](https://storage.googleapis.com/kldscp/amnezia.org/downloads)
|
||||
### [Website](https://amnezia.org) | [Alt website link](https://storage.googleapis.com/kldscp/amnezia.org) | [Documentation](https://docs.amnezia.org) | [Troubleshooting](https://docs.amnezia.org/troubleshooting)
|
||||
|
||||
> [!TIP]
|
||||
> If the [Amnezia website](https://amnezia.org) is blocked in your region, you can use an [Alternative website link](https://storage.googleapis.com/kldscp/amnezia.org).
|
||||
|
||||
<a href="https://amnezia.org/downloads"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/download-website.svg" width="150" style="max-width: 100%; margin-right: 10px"></a>
|
||||
<a href="https://storage.googleapis.com/kldscp/amnezia.org/downloads"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/download-alt.svg" width="150" style="max-width: 100%;"></a>
|
||||
|
||||
[All releases](https://github.com/amnezia-vpn/amnezia-client/releases)
|
||||
|
||||
<br>
|
||||
<br/>
|
||||
|
||||
<a href="https://www.testiny.io"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/testiny.png" height="28px"></a>
|
||||
|
||||
@@ -33,7 +38,8 @@ Amnezia is an open-source VPN client, with a key feature that enables you to dep
|
||||
|
||||
## Links
|
||||
|
||||
- [https://amnezia.org](https://amnezia.org) - project website | [Alternative link (mirror)](https://storage.googleapis.com/kldscp/amnezia.org)
|
||||
- [https://amnezia.org](https://amnezia.org) - Project website | [Alternative link (mirror)](https://storage.googleapis.com/kldscp/amnezia.org)
|
||||
- [https://docs.amnezia.org](https://docs.amnezia.org) - Documentation
|
||||
- [https://www.reddit.com/r/AmneziaVPN](https://www.reddit.com/r/AmneziaVPN) - Reddit
|
||||
- [https://t.me/amnezia_vpn_en](https://t.me/amnezia_vpn_en) - Telegram support channel (English)
|
||||
- [https://t.me/amnezia_vpn_ir](https://t.me/amnezia_vpn_ir) - Telegram support channel (Farsi)
|
||||
@@ -182,8 +188,8 @@ Patreon: [https://www.patreon.com/amneziavpn](https://www.patreon.com/amneziavpn
|
||||
Bitcoin: bc1q26eevjcg9j0wuyywd2e3uc9cs2w58lpkpjxq6p <br>
|
||||
USDT BEP20: 0x6abD576765a826f87D1D95183438f9408C901bE4 <br>
|
||||
USDT TRC20: TELAitazF1MZGmiNjTcnxDjEiH5oe7LC9d <br>
|
||||
XMR: 48spms39jt1L2L5vyw2RQW6CXD6odUd4jFu19GZcDyKKQV9U88wsJVjSbL4CfRys37jVMdoaWVPSvezCQPhHXUW5UKLqUp3
|
||||
|
||||
XMR: 48spms39jt1L2L5vyw2RQW6CXD6odUd4jFu19GZcDyKKQV9U88wsJVjSbL4CfRys37jVMdoaWVPSvezCQPhHXUW5UKLqUp3 <br>
|
||||
TON: UQDpU1CyKRmg7L8mNScKk9FRc2SlESuI7N-Hby4nX-CcVmns
|
||||
## Acknowledgments
|
||||
|
||||
This project is tested with BrowserStack.
|
||||
|
||||
181
README_RU.md
Normal file
@@ -0,0 +1,181 @@
|
||||
# Amnezia VPN
|
||||
|
||||
### _Лучший клиент для создания VPN на собственном сервере_
|
||||
|
||||
[](https://github.com/amnezia-vpn/amnezia-client/actions/workflows/deploy.yml?query=branch:dev)
|
||||
[](https://gitpod.io/#https://github.com/amnezia-vpn/amnezia-client)
|
||||
|
||||
### [English](https://github.com/amnezia-vpn/amnezia-client/blob/dev/README.md) | Русский
|
||||
[AmneziaVPN](https://amnezia.org) — это open sourse VPN-клиент, ключевая особенность которого заключается в возможности развернуть собственный VPN на вашем сервере.
|
||||
|
||||
[](https://amnezia.org)
|
||||
|
||||
### [Сайт](https://amnezia.org) | [Зеркало на сайт](https://storage.googleapis.com/kldscp/amnezia.org) | [Документация](https://docs.amnezia.org) | [Решение проблем](https://docs.amnezia.org/troubleshooting)
|
||||
|
||||
> [!TIP]
|
||||
> Если [сайт Amnezia](https://amnezia.org) заблокирован в вашем регионе, вы можете воспользоваться [ссылкой на зеркало](https://storage.googleapis.com/kldscp/amnezia.org).
|
||||
|
||||
<a href="https://storage.googleapis.com/kldscp/amnezia.org/downloads"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/download-website-ru.svg" width="150" style="max-width: 100%; margin-right: 10px"></a>
|
||||
|
||||
|
||||
[Все релизы](https://github.com/amnezia-vpn/amnezia-client/releases)
|
||||
|
||||
<br/>
|
||||
|
||||
<a href="https://www.testiny.io"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/testiny.png" height="28px"></a>
|
||||
|
||||
## Особенности
|
||||
|
||||
- Простой в использовании — введите IP-адрес, SSH-логин и пароль, и Amnezia автоматически установит VPN-контейнеры Docker на ваш сервер и подключится к VPN.
|
||||
- Классические VPN-протоколы: OpenVPN, WireGuard и IKEv2.
|
||||
- Протоколы с маскировкой трафика (обфускацией): OpenVPN с плагином [Cloak](https://github.com/cbeuw/Cloak), Shadowsocks (OpenVPN over Shadowsocks), [AmneziaWG](https://docs.amnezia.org/documentation/amnezia-wg/) and XRay.
|
||||
- Поддержка Split Tunneling — добавляйте любые сайты или приложения в список, чтобы включить VPN только для них.
|
||||
- Поддерживает платформы: Windows, MacOS, Linux, Android, iOS.
|
||||
- Поддержка конфигурации протокола AmneziaWG на [бета-прошивке Keenetic](https://docs.keenetic.com/ua/air/kn-1611/en/6319-latest-development-release.html#UUID-186c4108-5afd-c10b-f38a-cdff6c17fab3_section-idm33192196168192-improved).
|
||||
|
||||
## Ссылки
|
||||
|
||||
- [https://amnezia.org](https://amnezia.org) - Веб-сайт проекта | [Альтернативная ссылка (зеркало)](https://storage.googleapis.com/kldscp/amnezia.org)
|
||||
- [https://docs.amnezia.org](https://docs.amnezia.org) - Документация
|
||||
- [https://www.reddit.com/r/AmneziaVPN](https://www.reddit.com/r/AmneziaVPN) - Reddit
|
||||
- [https://t.me/amnezia_vpn_en](https://t.me/amnezia_vpn_en) - Канал поддржки в Telegram (Английский)
|
||||
- [https://t.me/amnezia_vpn_ir](https://t.me/amnezia_vpn_ir) - Канал поддржки в Telegram (Фарси)
|
||||
- [https://t.me/amnezia_vpn_mm](https://t.me/amnezia_vpn_mm) - Канал поддржки в Telegram (Мьянма)
|
||||
- [https://t.me/amnezia_vpn](https://t.me/amnezia_vpn) - Канал поддржки в Telegram (Русский)
|
||||
- [https://vpnpay.io/en/amnezia-premium/](https://vpnpay.io/en/amnezia-premium/) - Amnezia Premium | [Зеркало](https://storage.googleapis.com/kldscp/vpnpay.io/ru/amnezia-premium\)
|
||||
|
||||
## Технологии
|
||||
|
||||
AmneziaVPN использует несколько проектов с открытым исходным кодом:
|
||||
|
||||
- [OpenSSL](https://www.openssl.org/)
|
||||
- [OpenVPN](https://openvpn.net/)
|
||||
- [Shadowsocks](https://shadowsocks.org/)
|
||||
- [Qt](https://www.qt.io/)
|
||||
- [LibSsh](https://libssh.org)
|
||||
- и другие...
|
||||
|
||||
## Проверка исходного кода
|
||||
После клонирования репозитория обязательно загрузите все подмодули.
|
||||
|
||||
```bash
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
|
||||
## Разработка
|
||||
Хотите внести свой вклад? Добро пожаловать!
|
||||
|
||||
### Помощь с переводами
|
||||
|
||||
Загрузите самые актуальные файлы перевода.
|
||||
|
||||
Перейдите на [вкладку "Actions"](https://github.com/amnezia-vpn/amnezia-client/actions?query=is%3Asuccess+branch%3Adev), нажмите на первую строку. Затем прокрутите вниз до раздела "Artifacts" и скачайте "AmneziaVPN_translations".
|
||||
|
||||
Распакуйте этот файл. Каждый файл с расширением *.ts содержит строки для соответствующего языка.
|
||||
|
||||
Переведите или исправьте строки в одном или нескольких файлах *.ts и загрузите их обратно в этот репозиторий в папку ``client/translations``. Это можно сделать через веб-интерфейс или любым другим знакомым вам способом.
|
||||
|
||||
### Сборка исходного кода и деплой
|
||||
Проверьте папку deploy для скриптов сборки.
|
||||
|
||||
### Как собрать iOS-приложение из исходного кода на MacOS
|
||||
1. Убедитесь, что у вас установлен XCode версии 14 или выше.
|
||||
2. Для генерации проекта XCode используется QT. Требуется версия QT 6.6.2. Установите QT для MacOS здесь или через QT Online Installer. Необходимые модули:
|
||||
- MacOS
|
||||
- iOS
|
||||
- Модуль совместимости с Qt 5
|
||||
- Qt Shader Tools
|
||||
- Дополнительные библиотеки:
|
||||
- Qt Image Formats
|
||||
- Qt Multimedia
|
||||
- Qt Remote Objects
|
||||
|
||||
|
||||
3. Установите CMake, если это необходимо. Рекомендуемая версия — 3.25. Скачать CMake можно здесь.
|
||||
4. Установите Go версии >= v1.16. Если Go ещё не установлен, скачайте его с [официального сайта](https://golang.org/dl/) или используйте Homebrew. Установите gomobile:
|
||||
|
||||
```bash
|
||||
export PATH=$PATH:~/go/bin
|
||||
go install golang.org/x/mobile/cmd/gomobile@latest
|
||||
gomobile init
|
||||
```
|
||||
|
||||
5. Соберите проект:
|
||||
```bash
|
||||
export QT_BIN_DIR="<PATH-TO-QT-FOLDER>/Qt/<QT-VERSION>/ios/bin"
|
||||
export QT_MACOS_ROOT_DIR="<PATH-TO-QT-FOLDER>/Qt/<QT-VERSION>/macos"
|
||||
export QT_IOS_BIN=$QT_BIN_DIR
|
||||
export PATH=$PATH:~/go/bin
|
||||
mkdir build-ios
|
||||
$QT_IOS_BIN/qt-cmake . -B build-ios -GXcode -DQT_HOST_PATH=$QT_MACOS_ROOT_DIR
|
||||
```
|
||||
Замените <PATH-TO-QT-FOLDER> и <QT-VERSION> на ваши значения.
|
||||
|
||||
Если появляется ошибка gomobile: command not found, убедитесь, что PATH настроен на папку bin, где установлен gomobile:
|
||||
```bash
|
||||
export PATH=$(PATH):/path/to/GOPATH/bin
|
||||
```
|
||||
|
||||
6. Откройте проект в XCode. Теперь вы можете тестировать, архивировать или публиковать приложение.
|
||||
|
||||
Если сборка завершится с ошибкой:
|
||||
```
|
||||
make: ***
|
||||
[$(PROJECTDIR)/client/build/AmneziaVPN.build/Debug-iphoneos/wireguard-go-bridge/goroot/.prepared]
|
||||
Error 1
|
||||
```
|
||||
Добавьте пользовательскую переменную PATH в настройки сборки для целей AmneziaVPN и WireGuardNetworkExtension с ключом `PATH` и значением `${PATH}/path/to/bin/folder/with/go/executable`, e.g. `${PATH}:/usr/local/go/bin`.
|
||||
|
||||
Если ошибка повторяется на Mac с M1, установите версию CMake для архитектуры ARM:
|
||||
```
|
||||
arch -arm64 brew install cmake
|
||||
```
|
||||
|
||||
При первой попытке сборка может завершиться с ошибкой source files not found. Это происходит из-за параллельной компиляции зависимостей в XCode. Просто перезапустите сборку.
|
||||
|
||||
|
||||
## Как собрать Android-приложение
|
||||
Сборка тестировалась на MacOS. Требования:
|
||||
- JDK 11
|
||||
- Android SDK 33
|
||||
- CMake 3.25.0
|
||||
|
||||
Установите QT, QT Creator и Android Studio.
|
||||
Настройте QT Creator:
|
||||
|
||||
- В меню QT Creator перейдите в `QT Creator` -> `Preferences` -> `Devices` ->`Android`.
|
||||
- Укажите путь к JDK 11.
|
||||
- Укажите путь к Android SDK (`$ANDROID_HOME`)
|
||||
|
||||
Если вы сталкиваетесь с ошибками, связанными с отсутствием SDK или сообщением «SDK manager not running», их нельзя исправить просто корректировкой путей. Если у вас есть несколько свободных гигабайт на диске, вы можете позволить Qt Creator установить все необходимые компоненты, выбрав пустую папку для расположения Android SDK и нажав кнопку **Set Up SDK**. Учтите: это установит второй Android SDK и NDK на вашем компьютере!
|
||||
|
||||
Убедитесь, что настроена правильная версия CMake: перейдите в **Qt Creator -> Preferences** и в боковом меню выберите пункт **Kits**. В центральной части окна, на вкладке **Kits**, найдите запись для инструмента **CMake Tool**. Если выбранная по умолчанию версия CMake ниже 3.25.0, установите на свою систему CMake версии 3.25.0 или выше, а затем выберите опцию **System CMake at <путь>** из выпадающего списка. Если этот пункт отсутствует, это может означать, что вы еще не установили CMake, или Qt Creator не смог найти путь к нему. В таком случае в окне **Preferences** перейдите в боковое меню **CMake**, затем во вкладку **Tools** в центральной части окна и нажмите кнопку **Add**, чтобы указать путь к установленному CMake.
|
||||
|
||||
Убедитесь, что для вашего проекта выбрана Android Platform SDK 33: в главном окне на боковой панели выберите пункт **Projects**, и слева вы увидите раздел **Build & Run**, показывающий различные целевые Android-платформы. Вы можете выбрать любую из них, так как настройка проекта Amnezia VPN разработана таким образом, чтобы все Android-цели могли быть собраны. Перейдите в подраздел **Build** и прокрутите центральную часть окна до раздела **Build Steps**. Нажмите **Details** в заголовке **Build Android APK** (кнопка **Details** может быть скрыта, если окно Qt Creator не запущено в полноэкранном режиме!). Вот здесь выберите **android-33** в качестве Android Build Platform SDK.
|
||||
|
||||
### Разработка Android-компонентов
|
||||
|
||||
После сборки QT Creator копирует проект в отдельную папку, например, `build-amnezia-client-Android_Qt_<version>_Clang_<architecture>-<BuildType>`. Для разработки Android-компонентов откройте сгенерированный проект в Android Studio, указав папку `build-amnezia-client-Android_Qt_<version>_Clang_<architecture>-<BuildType>/client/android-build` в качестве корневой.
|
||||
Изменения в сгенерированном проекте нужно вручную перенести в репозиторий. После этого можно коммитить изменения.
|
||||
Если возникают проблемы со сборкой в QT Creator после работы в Android Studio, выполните команду `./gradlew clean` в корневой папке сгенерированного проекта (`<path>/client/android-build/.`).
|
||||
|
||||
|
||||
## Лицензия
|
||||
|
||||
GPL v3.0
|
||||
|
||||
## Донаты
|
||||
|
||||
Patreon: [https://www.patreon.com/amneziavpn](https://www.patreon.com/amneziavpn)
|
||||
|
||||
Bitcoin: bc1q26eevjcg9j0wuyywd2e3uc9cs2w58lpkpjxq6p <br>
|
||||
USDT BEP20: 0x6abD576765a826f87D1D95183438f9408C901bE4 <br>
|
||||
USDT TRC20: TELAitazF1MZGmiNjTcnxDjEiH5oe7LC9d <br>
|
||||
XMR: 48spms39jt1L2L5vyw2RQW6CXD6odUd4jFu19GZcDyKKQV9U88wsJVjSbL4CfRys37jVMdoaWVPSvezCQPhHXUW5UKLqUp3 <br>
|
||||
TON: UQDpU1CyKRmg7L8mNScKk9FRc2SlESuI7N-Hby4nX-CcVmns
|
||||
|
||||
## Благодарности
|
||||
|
||||
Этот проект тестируется с помощью BrowserStack.
|
||||
Мы выражаем благодарность [BrowserStack](https://www.browserstack.com) за поддержку нашего проекта.
|
||||
2
client/3rd/OpenVPNAdapter
vendored
2
client/3rd/amneziawg-apple
vendored
@@ -31,12 +31,11 @@ add_definitions(-DDEV_AGW_PUBLIC_KEY="$ENV{DEV_AGW_PUBLIC_KEY}")
|
||||
add_definitions(-DDEV_AGW_ENDPOINT="$ENV{DEV_AGW_ENDPOINT}")
|
||||
add_definitions(-DDEV_S3_ENDPOINT="$ENV{DEV_S3_ENDPOINT}")
|
||||
|
||||
if(IOS OR MACOS_NE)
|
||||
if(IOS)
|
||||
set(PACKAGES ${PACKAGES} Multimedia)
|
||||
endif()
|
||||
|
||||
#Macos Network Extension doesn't need Widgets
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
|
||||
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||
set(PACKAGES ${PACKAGES} Widgets)
|
||||
endif()
|
||||
|
||||
@@ -49,23 +48,18 @@ set(LIBS ${LIBS}
|
||||
Qt6::Core5Compat Qt6::Concurrent
|
||||
)
|
||||
|
||||
if(IOS OR MACOS_NE)
|
||||
if(IOS)
|
||||
set(LIBS ${LIBS} Qt6::Multimedia)
|
||||
endif()
|
||||
# message("Client desktop build ", ${MACOS_NE})
|
||||
#Macos Network Extension doesn't need Widgets
|
||||
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
|
||||
message("Run this block when MACOS_NE is not defined or set to FALSE")
|
||||
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||
set(LIBS ${LIBS} Qt6::Widgets)
|
||||
endif()
|
||||
|
||||
qt_standard_project_setup()
|
||||
qt_add_executable(${PROJECT} MANUAL_FINALIZATION)
|
||||
|
||||
# TODO error in there
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
|
||||
message("Run this block when MACOS_NE is not defined or set to FALSE")
|
||||
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_interface.rep)
|
||||
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_process_interface.rep)
|
||||
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_process_tun2socks.rep)
|
||||
@@ -103,18 +97,10 @@ qt6_add_resources(QRC ${I18NQRC} ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc)
|
||||
# -- i18n end
|
||||
|
||||
if(IOS)
|
||||
message("Building for iOS")
|
||||
execute_process(COMMAND bash ${CMAKE_CURRENT_LIST_DIR}/ios/scripts/openvpn.sh args
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
endif()
|
||||
|
||||
# Build openvpn adapter for MacOS Network Extension
|
||||
if(MACOS_NE)
|
||||
message("Building for MacOS Network Extension")
|
||||
execute_process(COMMAND bash ${CMAKE_CURRENT_LIST_DIR}/macos/scripts/openvpn.sh args
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
endif()
|
||||
|
||||
set(IS_CI ${CI})
|
||||
if(IS_CI)
|
||||
message("Detected CI env")
|
||||
@@ -160,6 +146,7 @@ set(HEADERS ${HEADERS}
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/transfer.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/enums/apiEnums.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/../common/logger/logger.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/utils/qmlUtils.h
|
||||
)
|
||||
|
||||
# Mozilla headres
|
||||
@@ -175,24 +162,12 @@ include_directories(mozilla)
|
||||
include_directories(mozilla/shared)
|
||||
include_directories(mozilla/models)
|
||||
|
||||
if(MACOS_NE)
|
||||
message("MACOS_NE is ON")
|
||||
add_definitions(-DQ_OS_IOS)
|
||||
add_definitions(-DMACOS_NE)
|
||||
message("Add macros for MacOS Network Extension")
|
||||
else()
|
||||
message("MACOS_NE is OFF")
|
||||
endif()
|
||||
|
||||
|
||||
if(NOT IOS AND NOT MACOS_NE)
|
||||
message(" Add header for non-IOS and non-MACOS_NE")
|
||||
if(NOT IOS)
|
||||
set(HEADERS ${HEADERS}
|
||||
${CMAKE_CURRENT_LIST_DIR}/platforms/ios/QRCodeReaderBase.h
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
if(NOT ANDROID)
|
||||
set(HEADERS ${HEADERS}
|
||||
${CMAKE_CURRENT_LIST_DIR}/ui/notificationhandler.h
|
||||
@@ -223,6 +198,7 @@ set(SOURCES ${SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/vmess.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/vmess_new.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../common/logger/logger.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/utils/qmlUtils.cpp
|
||||
)
|
||||
|
||||
# Mozilla sources
|
||||
@@ -237,7 +213,7 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
target_compile_definitions(${PROJECT} PRIVATE "MZ_DEBUG")
|
||||
endif()
|
||||
|
||||
if(NOT IOS AND NOT MACOS_NE)
|
||||
if(NOT IOS)
|
||||
set(SOURCES ${SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/platforms/ios/QRCodeReaderBase.cpp
|
||||
)
|
||||
@@ -338,7 +314,6 @@ if(APPLE)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM ${BUILD_VPN_DEVELOPMENT_TEAM})
|
||||
set(CMAKE_XCODE_ATTRIBUTE_GROUP_ID_IOS ${BUILD_IOS_GROUP_IDENTIFIER})
|
||||
|
||||
set(MACOSX_DEPLOYMENT_TARGET "12.0")
|
||||
endif()
|
||||
|
||||
if(LINUX AND NOT ANDROID)
|
||||
@@ -346,9 +321,10 @@ if(LINUX AND NOT ANDROID)
|
||||
link_directories(${CMAKE_CURRENT_LIST_DIR}/platforms/linux)
|
||||
endif()
|
||||
|
||||
# Macos Network Extension doesn't need
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
|
||||
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||
message("Client desktop build")
|
||||
add_compile_definitions(AMNEZIA_DESKTOP)
|
||||
|
||||
set(HEADERS ${HEADERS}
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/ipcclient.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/privileged_process.h
|
||||
@@ -381,12 +357,9 @@ endif()
|
||||
if(IOS)
|
||||
include(cmake/ios.cmake)
|
||||
include(cmake/ios-arch-fixup.cmake)
|
||||
elseif(APPLE AND NOT IOS AND NOT DEFINED MACOS_NE)
|
||||
# include(cmake/osxtools.cmake)
|
||||
include(cmake/macos.cmake)
|
||||
elseif(APPLE AND NOT IOS AND MACOS_NE)
|
||||
elseif(APPLE AND NOT IOS)
|
||||
include(cmake/osxtools.cmake)
|
||||
include(cmake/macos_ne.cmake)
|
||||
include(cmake/macos.cmake)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${PROJECT} PRIVATE ${LIBS})
|
||||
@@ -405,7 +378,7 @@ elseif(APPLE AND NOT IOS)
|
||||
set(DEPLOY_PLATFORM_PATH "macos")
|
||||
endif()
|
||||
|
||||
if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
|
||||
if(NOT IOS AND NOT ANDROID)
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E $<IF:$<CONFIG:Debug>,copy_directory,true>
|
||||
@@ -424,36 +397,4 @@ if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
|
||||
endif()
|
||||
|
||||
target_sources(${PROJECT} PRIVATE ${SOURCES} ${HEADERS} ${RESOURCES} ${QRC} ${I18NQRC})
|
||||
if(MACOS_NE)
|
||||
message("Copy MacOS Network Extension files")
|
||||
|
||||
add_custom_command(TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory
|
||||
$<TARGET_BUNDLE_DIR:AmneziaVPN>/Contents/Frameworks
|
||||
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Copying OpenVPNAdapter.framework..."
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_SOURCE_DIR}/client/3rd/OpenVPNAdapter/build/Release-macos/OpenVPNAdapter.framework/Versions/A
|
||||
$<TARGET_BUNDLE_DIR:AmneziaVPN>/Contents/Frameworks/OpenVPNAdapter.framework/Versions/A
|
||||
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "OpenVPNAdapter.framework copied successfully."
|
||||
)
|
||||
|
||||
# MacOS specific application deployment
|
||||
add_custom_command(TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${QT_BIN_DIR_DETECTED}/macdeployqt $<TARGET_BUNDLE_DIR:AmneziaVPN> -appstore-compliant -qmldir=${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
# MacOS specific code signing for Release
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
SET(SIGN_CMD codesign --deep --force --sign 'Apple Distribution: Privacy Technologies OU \(X7UJ388FXK\)' --timestamp --options runtime $<TARGET_BUNDLE_DIR:AmneziaVPN>)
|
||||
message("Manual signing bundle...")
|
||||
message(${SIGN_CMD})
|
||||
|
||||
add_custom_command(TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${SIGN_CMD}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
qt_finalize_target(${PROJECT})
|
||||
|
||||
@@ -404,6 +404,9 @@ void AmneziaApplication::initControllers()
|
||||
m_pageController.reset(new PageController(m_serversModel, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("PageController", m_pageController.get());
|
||||
|
||||
m_focusController.reset(new FocusController(m_engine, this));
|
||||
m_engine->rootContext()->setContextProperty("FocusController", m_focusController.get());
|
||||
|
||||
m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_protocolsModel, m_clientManagementModel,
|
||||
m_apiServicesModel, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("InstallController", m_installController.get());
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "ui/controllers/exportController.h"
|
||||
#include "ui/controllers/importController.h"
|
||||
#include "ui/controllers/installController.h"
|
||||
#include "ui/controllers/focusController.h"
|
||||
#include "ui/controllers/pageController.h"
|
||||
#include "ui/controllers/settingsController.h"
|
||||
#include "ui/controllers/sitesController.h"
|
||||
@@ -124,6 +125,7 @@ private:
|
||||
#endif
|
||||
|
||||
QScopedPointer<ConnectionController> m_connectionController;
|
||||
QScopedPointer<FocusController> m_focusController;
|
||||
QScopedPointer<PageController> m_pageController;
|
||||
QScopedPointer<InstallController> m_installController;
|
||||
QScopedPointer<ImportController> m_importController;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<uses-feature android:name="android.hardware.camera.any" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
|
||||
<!-- for TV -->
|
||||
<uses-feature android:name="android.software.leanback" android:required="false" />
|
||||
<uses-feature android:name="android.software.leanback" android:required="true" />
|
||||
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
|
||||
|
||||
<!-- The following comment will be replaced upon deployment with default features based on the dependencies
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<!-- To request network state -->
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" android:maxSdkVersion="30" />
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
@@ -91,6 +91,13 @@
|
||||
android:exported="false"
|
||||
android:theme="@style/Translucent" />
|
||||
|
||||
<activity android:name=".TvFilePicker"
|
||||
android:excludeFromRecents="true"
|
||||
android:launchMode="singleTask"
|
||||
android:taskAffinity=""
|
||||
android:exported="false"
|
||||
android:theme="@style/Translucent" />
|
||||
|
||||
<activity
|
||||
android:name=".ImportConfigActivity"
|
||||
android:excludeFromRecents="true"
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_banner_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_banner_foreground"/>
|
||||
</adaptive-icon>
|
||||
BIN
client/android/res/mipmap-hdpi/ic_banner.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
client/android/res/mipmap-mdpi/ic_banner.png
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 12 KiB |
@@ -23,4 +23,6 @@
|
||||
<string name="notificationSettingsDialogTitle">Настройки уведомлений</string>
|
||||
<string name="notificationSettingsDialogMessage">Для показа уведомлений необходимо включить уведомления в системных настройках</string>
|
||||
<string name="openNotificationSettings">Открыть настройки уведомлений</string>
|
||||
|
||||
<string name="tvNoFileBrowser">Пожалуйста, установите приложение для просмотра файлов</string>
|
||||
</resources>
|
||||
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_banner_background">#1E1E1F</color>
|
||||
</resources>
|
||||
@@ -23,4 +23,6 @@
|
||||
<string name="notificationSettingsDialogTitle">Notification settings</string>
|
||||
<string name="notificationSettingsDialogMessage">To show notifications, you must enable notifications in the system settings</string>
|
||||
<string name="openNotificationSettings">Open notification settings</string>
|
||||
|
||||
<string name="tvNoFileBrowser">Please install a file management utility to browse files</string>
|
||||
</resources>
|
||||
@@ -4,6 +4,7 @@ import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.AlertDialog
|
||||
import android.app.NotificationManager
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
@@ -12,6 +13,7 @@ import android.content.Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
|
||||
import android.content.ServiceConnection
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.net.VpnService
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
@@ -20,8 +22,13 @@ import android.os.IBinder
|
||||
import android.os.Looper
|
||||
import android.os.Message
|
||||
import android.os.Messenger
|
||||
import android.os.ParcelFileDescriptor
|
||||
import android.os.SystemClock
|
||||
import android.provider.OpenableColumns
|
||||
import android.provider.Settings
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager.LayoutParams
|
||||
import android.webkit.MimeTypeMap
|
||||
import android.widget.Toast
|
||||
@@ -30,6 +37,7 @@ import androidx.annotation.RequiresApi
|
||||
import androidx.core.content.ContextCompat
|
||||
import java.io.IOException
|
||||
import kotlin.LazyThreadSafetyMode.NONE
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.text.RegexOption.IGNORE_CASE
|
||||
import AppListProvider
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
@@ -71,6 +79,7 @@ class AmneziaActivity : QtActivity() {
|
||||
private var isInBoundState = false
|
||||
private var notificationStateReceiver: BroadcastReceiver? = null
|
||||
private lateinit var vpnServiceMessenger: IpcMessenger
|
||||
private var pfd: ParcelFileDescriptor? = null
|
||||
|
||||
private val actionResultHandlers = mutableMapOf<Int, ActivityResultHandler>()
|
||||
private val permissionRequestHandlers = mutableMapOf<Int, PermissionRequestHandler>()
|
||||
@@ -514,21 +523,25 @@ class AmneziaActivity : QtActivity() {
|
||||
type = "text/*"
|
||||
putExtra(Intent.EXTRA_TITLE, fileName)
|
||||
}.also {
|
||||
startActivityForResult(it, CREATE_FILE_ACTION_CODE, ActivityResultHandler(
|
||||
onSuccess = {
|
||||
it?.data?.let { uri ->
|
||||
Log.v(TAG, "Save file to $uri")
|
||||
try {
|
||||
contentResolver.openOutputStream(uri)?.use { os ->
|
||||
os.bufferedWriter().use { it.write(data) }
|
||||
try {
|
||||
startActivityForResult(it, CREATE_FILE_ACTION_CODE, ActivityResultHandler(
|
||||
onSuccess = {
|
||||
it?.data?.let { uri ->
|
||||
Log.v(TAG, "Save file to $uri")
|
||||
try {
|
||||
contentResolver.openOutputStream(uri)?.use { os ->
|
||||
os.bufferedWriter().use { it.write(data) }
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
Log.e(TAG, "Failed to save file $uri: $e")
|
||||
// todo: send error to Qt
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
Log.e(TAG, "Failed to save file $uri: $e")
|
||||
// todo: send error to Qt
|
||||
}
|
||||
}
|
||||
}
|
||||
))
|
||||
))
|
||||
} catch (_: ActivityNotFoundException) {
|
||||
Toast.makeText(this@AmneziaActivity, "Unsupported", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -537,35 +550,46 @@ class AmneziaActivity : QtActivity() {
|
||||
fun openFile(filter: String?) {
|
||||
Log.v(TAG, "Open file with filter: $filter")
|
||||
mainScope.launch {
|
||||
val mimeTypes = if (!filter.isNullOrEmpty()) {
|
||||
val extensionRegex = "\\*\\.([a-z0-9]+)".toRegex(IGNORE_CASE)
|
||||
val mime = MimeTypeMap.getSingleton()
|
||||
extensionRegex.findAll(filter).map {
|
||||
it.groups[1]?.value?.let { mime.getMimeTypeFromExtension(it) } ?: "*/*"
|
||||
}.toSet()
|
||||
} else emptySet()
|
||||
val intent = if (!isOnTv()) {
|
||||
val mimeTypes = if (!filter.isNullOrEmpty()) {
|
||||
val extensionRegex = "\\*\\.([a-z0-9]+)".toRegex(IGNORE_CASE)
|
||||
val mime = MimeTypeMap.getSingleton()
|
||||
extensionRegex.findAll(filter).map {
|
||||
it.groups[1]?.value?.let { mime.getMimeTypeFromExtension(it) } ?: "*/*"
|
||||
}.toSet()
|
||||
} else emptySet()
|
||||
|
||||
Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
Log.v(TAG, "File mimyType filter: $mimeTypes")
|
||||
if ("*/*" in mimeTypes) {
|
||||
type = "*/*"
|
||||
} else {
|
||||
when (mimeTypes.size) {
|
||||
1 -> type = mimeTypes.first()
|
||||
Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
Log.v(TAG, "File mimyType filter: $mimeTypes")
|
||||
if ("*/*" in mimeTypes) {
|
||||
type = "*/*"
|
||||
} else {
|
||||
when (mimeTypes.size) {
|
||||
1 -> type = mimeTypes.first()
|
||||
|
||||
in 2..Int.MAX_VALUE -> {
|
||||
type = "*/*"
|
||||
putExtra(EXTRA_MIME_TYPES, mimeTypes.toTypedArray())
|
||||
in 2..Int.MAX_VALUE -> {
|
||||
type = "*/*"
|
||||
putExtra(EXTRA_MIME_TYPES, mimeTypes.toTypedArray())
|
||||
}
|
||||
|
||||
else -> type = "*/*"
|
||||
}
|
||||
|
||||
else -> type = "*/*"
|
||||
}
|
||||
}
|
||||
}.also {
|
||||
startActivityForResult(it, OPEN_FILE_ACTION_CODE, ActivityResultHandler(
|
||||
} else {
|
||||
Intent(this@AmneziaActivity, TvFilePicker::class.java)
|
||||
}
|
||||
|
||||
try {
|
||||
startActivityForResult(intent, OPEN_FILE_ACTION_CODE, ActivityResultHandler(
|
||||
onAny = {
|
||||
val uri = it?.data?.toString() ?: ""
|
||||
if (isOnTv() && it?.hasExtra("activityNotFound") == true) {
|
||||
showNoFileBrowserAlertDialog()
|
||||
}
|
||||
val uri = it?.data?.apply {
|
||||
grantUriPermission(packageName, this, Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
}?.toString() ?: ""
|
||||
Log.v(TAG, "Open file: $uri")
|
||||
mainScope.launch {
|
||||
qtInitialized.await()
|
||||
@@ -573,10 +597,68 @@ class AmneziaActivity : QtActivity() {
|
||||
}
|
||||
}
|
||||
))
|
||||
} catch (_: ActivityNotFoundException) {
|
||||
showNoFileBrowserAlertDialog()
|
||||
mainScope.launch {
|
||||
qtInitialized.await()
|
||||
QtAndroidController.onFileOpened("")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showNoFileBrowserAlertDialog() {
|
||||
AlertDialog.Builder(this)
|
||||
.setMessage(R.string.tvNoFileBrowser)
|
||||
.setCancelable(false)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
try {
|
||||
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("market://webstoreredirect")))
|
||||
} catch (_: Throwable) {}
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun getFd(fileName: String): Int {
|
||||
Log.v(TAG, "Get fd for $fileName")
|
||||
return blockingCall {
|
||||
try {
|
||||
pfd = contentResolver.openFileDescriptor(Uri.parse(fileName), "r")
|
||||
pfd?.fd ?: -1
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to get fd: $e")
|
||||
-1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun closeFd() {
|
||||
Log.v(TAG, "Close fd")
|
||||
mainScope.launch {
|
||||
pfd?.close()
|
||||
pfd = null
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun getFileName(uri: String): String {
|
||||
Log.v(TAG, "Get file name for uri: $uri")
|
||||
return blockingCall {
|
||||
try {
|
||||
contentResolver.query(Uri.parse(uri), arrayOf(OpenableColumns.DISPLAY_NAME), null, null, null)?.use { cursor ->
|
||||
if (cursor.moveToFirst() && !cursor.isNull(0)) {
|
||||
return@blockingCall cursor.getString(0) ?: ""
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to get file name: $e")
|
||||
}
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
@SuppressLint("UnsupportedChromeOsCameraSystemFeature")
|
||||
fun isCameraPresent(): Boolean = applicationContext.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)
|
||||
@@ -721,6 +803,50 @@ class AmneziaActivity : QtActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
// method to workaround Qt's problem with calling the keyboard on TVs
|
||||
@Suppress("unused")
|
||||
fun sendTouch(x: Float, y: Float) {
|
||||
Log.v(TAG, "Send touch: $x, $y")
|
||||
blockingCall {
|
||||
findQtWindow(window.decorView)?.let {
|
||||
Log.v(TAG, "Send touch to $it")
|
||||
it.dispatchTouchEvent(createEvent(x, y, SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN))
|
||||
it.dispatchTouchEvent(createEvent(x, y, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun findQtWindow(view: View): View? {
|
||||
Log.v(TAG, "findQtWindow: process $view")
|
||||
if (view::class.simpleName == "QtWindow") return view
|
||||
else if (view is ViewGroup) {
|
||||
for (i in 0 until view.childCount) {
|
||||
val result = findQtWindow(view.getChildAt(i))
|
||||
if (result != null) return result
|
||||
}
|
||||
return null
|
||||
} else return null
|
||||
}
|
||||
|
||||
private fun createEvent(x: Float, y: Float, eventTime: Long, action: Int): MotionEvent =
|
||||
MotionEvent.obtain(
|
||||
eventTime,
|
||||
eventTime,
|
||||
action,
|
||||
1,
|
||||
arrayOf(MotionEvent.PointerProperties().apply {
|
||||
id = 0
|
||||
toolType = MotionEvent.TOOL_TYPE_FINGER
|
||||
}),
|
||||
arrayOf(MotionEvent.PointerCoords().apply {
|
||||
this.x = x
|
||||
this.y = y
|
||||
pressure = 1f
|
||||
size = 1f
|
||||
}),
|
||||
0, 0, 1.0f, 1.0f, 0, 0, 0,0
|
||||
)
|
||||
|
||||
// workaround for a bug in Qt that causes the mouse click event not to be handled
|
||||
// also disable right-click, as it causes the application to crash
|
||||
private var lastButtonState = 0
|
||||
@@ -770,6 +896,7 @@ class AmneziaActivity : QtActivity() {
|
||||
}
|
||||
|
||||
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
|
||||
Log.v(TAG, "dispatchTouch: $ev")
|
||||
if (ev != null && ev.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) {
|
||||
return handleMouseEvent(ev) { super.dispatchTouchEvent(it) }
|
||||
}
|
||||
@@ -784,6 +911,13 @@ class AmneziaActivity : QtActivity() {
|
||||
/**
|
||||
* Utils methods
|
||||
*/
|
||||
private fun <T> blockingCall(
|
||||
context: CoroutineContext = Dispatchers.Main.immediate,
|
||||
block: suspend () -> T
|
||||
) = runBlocking {
|
||||
mainScope.async(context) { block() }.await()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun actionCodeToString(actionCode: Int): String =
|
||||
when (actionCode) {
|
||||
|
||||
45
client/android/src/org/amnezia/vpn/TvFilePicker.kt
Normal file
@@ -0,0 +1,45 @@
|
||||
package org.amnezia.vpn
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import org.amnezia.vpn.util.Log
|
||||
|
||||
private const val TAG = "TvFilePicker"
|
||||
|
||||
class TvFilePicker : ComponentActivity() {
|
||||
|
||||
private val fileChooseResultLauncher = registerForActivityResult(ActivityResultContracts.GetContent()) {
|
||||
setResult(RESULT_OK, Intent().apply { data = it })
|
||||
finish()
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
Log.v(TAG, "onCreate")
|
||||
getFile()
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent) {
|
||||
super.onNewIntent(intent)
|
||||
Log.v(TAG, "onNewIntent")
|
||||
getFile()
|
||||
}
|
||||
|
||||
private fun getFile() {
|
||||
try {
|
||||
Log.v(TAG, "getFile")
|
||||
fileChooseResultLauncher.launch("*/*")
|
||||
} catch (_: ActivityNotFoundException) {
|
||||
Log.w(TAG, "Activity not found")
|
||||
setResult(RESULT_CANCELED, Intent().apply { putExtra("activityNotFound", true) })
|
||||
finish()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to get file: $e")
|
||||
setResult(RESULT_CANCELED)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
package org.amnezia.vpn.protocol.wireguard
|
||||
|
||||
import android.net.VpnService.Builder
|
||||
import java.io.IOException
|
||||
import java.util.Locale
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.launch
|
||||
import org.amnezia.awg.GoBackend
|
||||
import org.amnezia.vpn.protocol.Protocol
|
||||
import org.amnezia.vpn.protocol.ProtocolState.CONNECTED
|
||||
@@ -27,6 +28,8 @@ open class Wireguard : Protocol() {
|
||||
|
||||
private var tunnelHandle: Int = -1
|
||||
protected open val ifName: String = "amn0"
|
||||
private lateinit var scope: CoroutineScope
|
||||
private var statusJob: Job? = null
|
||||
|
||||
override val statistics: Statistics
|
||||
get() {
|
||||
@@ -49,46 +52,17 @@ open class Wireguard : Protocol() {
|
||||
|
||||
override fun internalInit() {
|
||||
if (!isInitialized) loadSharedLibrary(context, "wg-go")
|
||||
if (this::scope.isInitialized) {
|
||||
scope.cancel()
|
||||
}
|
||||
scope = CoroutineScope(Dispatchers.IO)
|
||||
}
|
||||
|
||||
override suspend fun startVpn(config: JSONObject, vpnBuilder: Builder, protect: (Int) -> Boolean) {
|
||||
val wireguardConfig = parseConfig(config)
|
||||
val startTime = System.currentTimeMillis()
|
||||
start(wireguardConfig, vpnBuilder, protect)
|
||||
waitForConnection(startTime)
|
||||
state.value = CONNECTED
|
||||
}
|
||||
|
||||
private suspend fun waitForConnection(startTime: Long) {
|
||||
Log.d(TAG, "Waiting for connection")
|
||||
withContext(Dispatchers.IO) {
|
||||
val time = String.format(Locale.ROOT,"%.3f", startTime / 1000.0)
|
||||
try {
|
||||
delay(1000)
|
||||
var log = getLogcat(time)
|
||||
Log.v(TAG, "First waiting log: $log")
|
||||
// check that there is a connection log,
|
||||
// to avoid infinite connection
|
||||
if (!log.contains("Attaching to interface")) {
|
||||
Log.w(TAG, "Logs do not contain a connection log")
|
||||
return@withContext
|
||||
}
|
||||
while (!log.contains("Received handshake response")) {
|
||||
delay(1000)
|
||||
log = getLogcat(time)
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
Log.e(TAG, "Failed to get logcat: $e")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getLogcat(time: String): String =
|
||||
ProcessBuilder("logcat", "--buffer=main", "--format=raw", "*:S AmneziaWG/awg0", "-t", time)
|
||||
.redirectErrorStream(true)
|
||||
.start()
|
||||
.inputStream.reader().readText()
|
||||
|
||||
protected open fun parseConfig(config: JSONObject): WireguardConfig {
|
||||
val configData = config.getJSONObject("wireguard_config_data")
|
||||
return WireguardConfig.build {
|
||||
@@ -178,6 +152,43 @@ open class Wireguard : Protocol() {
|
||||
tunnelHandle = -1
|
||||
throw VpnStartException("Protect VPN interface: permission not granted or revoked")
|
||||
}
|
||||
launchStatusJob()
|
||||
}
|
||||
|
||||
private fun launchStatusJob() {
|
||||
Log.d(TAG, "Launch status job")
|
||||
statusJob = scope.launch {
|
||||
while (true) {
|
||||
val lastHandshake = getLastHandshake()
|
||||
Log.v(TAG, "lastHandshake=$lastHandshake")
|
||||
if (lastHandshake == 0L) {
|
||||
delay(1000)
|
||||
continue
|
||||
}
|
||||
if (lastHandshake == -2L || lastHandshake > 0L) state.value = CONNECTED
|
||||
else if (lastHandshake == -1L) state.value = DISCONNECTED
|
||||
statusJob = null
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getLastHandshake(): Long {
|
||||
if (tunnelHandle == -1) {
|
||||
Log.e(TAG, "Trying to get config of a non-existent tunnel")
|
||||
return -1
|
||||
}
|
||||
val config = GoBackend.awgGetConfig(tunnelHandle)
|
||||
if (config == null) {
|
||||
Log.e(TAG, "Failed to get tunnel config")
|
||||
return -2
|
||||
}
|
||||
val lastHandshake = config.lines().find { it.startsWith("last_handshake_time_sec=") }?.substring(24)?.toLong()
|
||||
if (lastHandshake == null) {
|
||||
Log.e(TAG, "Failed to get last_handshake_time_sec")
|
||||
return -2
|
||||
}
|
||||
return lastHandshake
|
||||
}
|
||||
|
||||
override fun stopVpn() {
|
||||
@@ -185,6 +196,8 @@ open class Wireguard : Protocol() {
|
||||
Log.w(TAG, "Tunnel already down")
|
||||
return
|
||||
}
|
||||
statusJob?.cancel()
|
||||
statusJob = null
|
||||
val handleToClose = tunnelHandle
|
||||
tunnelHandle = -1
|
||||
GoBackend.awgTurnOff(handleToClose)
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
message("Client ==> MacOS NE build")
|
||||
|
||||
set_target_properties(${PROJECT} PROPERTIES MACOSX_BUNDLE TRUE)
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym")
|
||||
set(APPLE_PROJECT_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
||||
|
||||
|
||||
enable_language(OBJC)
|
||||
enable_language(Swift)
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS ShaderTools)
|
||||
set(LIBS ${LIBS} Qt6::ShaderTools)
|
||||
|
||||
find_library(FW_AUTHENTICATIONSERVICES AuthenticationServices)
|
||||
find_library(FW_AVFOUNDATION AVFoundation)
|
||||
find_library(FW_FOUNDATION Foundation)
|
||||
find_library(FW_STOREKIT StoreKit)
|
||||
find_library(FW_USERNOTIFICATIONS UserNotifications)
|
||||
find_library(FW_NETWORKEXTENSION NetworkExtension)
|
||||
|
||||
set(LIBS ${LIBS}
|
||||
${FW_AUTHENTICATIONSERVICES}
|
||||
${FW_AVFOUNDATION}
|
||||
${FW_FOUNDATION}
|
||||
${FW_STOREKIT}
|
||||
${FW_USERNOTIFICATIONS}
|
||||
${FW_NETWORKEXTENSION}
|
||||
)
|
||||
|
||||
|
||||
set(HEADERS ${HEADERS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/ios_controller.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/ios_controller_wrapper.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/iosnotificationhandler.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/QtAppDelegate.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/QtAppDelegate-C-Interface.h
|
||||
)
|
||||
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/ios_controller.h PROPERTIES OBJECTIVE_CPP_HEADER TRUE)
|
||||
|
||||
|
||||
set(SOURCES ${SOURCES}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/ios_controller.mm
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/ios_controller_wrapper.mm
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/iosnotificationhandler.mm
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/iosglue.mm
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/QRCodeReaderBase.mm
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/QtAppDelegate.mm
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT} PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
||||
|
||||
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Info.plist.in
|
||||
MACOSX_BUNDLE_ICON_FILE "AppIcon"
|
||||
MACOSX_BUNDLE_INFO_STRING "AmneziaVPN"
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "AmneziaVPN"
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
MACOSX_BUNDLE_LONG_VERSION_STRING "${APPLE_PROJECT_VERSION}-${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${APPLE_PROJECT_VERSION}"
|
||||
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${BUILD_IOS_APP_IDENTIFIER}"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/ios/app/main.entitlements"
|
||||
XCODE_ATTRIBUTE_MARKETING_VERSION "${APPLE_PROJECT_VERSION}"
|
||||
XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
XCODE_ATTRIBUTE_PRODUCT_NAME "AmneziaVPN"
|
||||
XCODE_ATTRIBUTE_BUNDLE_INFO_STRING "AmneziaVPN"
|
||||
XCODE_GENERATE_SCHEME TRUE
|
||||
XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
|
||||
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon"
|
||||
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
|
||||
XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY "NO"
|
||||
XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY "YES"
|
||||
|
||||
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
|
||||
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../Frameworks"
|
||||
XCODE_EMBED_APP_EXTENSIONS networkextension
|
||||
|
||||
# XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution: Privacy Technologies OU (X7UJ388FXK)"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "Mac AppStore AmneziaVPN"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "org.amnezia.AmneziaVPNManual"
|
||||
)
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
|
||||
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES "YES"
|
||||
XCODE_ATTRIBUTE_SWIFT_PRECOMPILE_BRIDGING_HEADER "NO"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_INTERFACE_HEADER_NAME "AmneziaVPN-Swift.h"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_INTEROP_MODE "objcxx"
|
||||
)
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "X7UJ388FXK"
|
||||
)
|
||||
target_include_directories(${PROJECT} PRIVATE ${CMAKE_CURRENT_LIST_DIR})
|
||||
target_compile_options(${PROJECT} PRIVATE
|
||||
-DGROUP_ID=\"${BUILD_IOS_GROUP_IDENTIFIER}\"
|
||||
-DVPN_NE_BUNDLEID=\"${BUILD_IOS_APP_IDENTIFIER}.network-extension\"
|
||||
)
|
||||
|
||||
set(WG_APPLE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rd/amneziawg-apple/Sources)
|
||||
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKitC/x25519.c
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/LogController.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/Log.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/LogRecord.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/ScreenProtection.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/VPNCController.swift
|
||||
)
|
||||
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Images.xcassets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Images.xcassets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
add_subdirectory(macos/networkextension)
|
||||
add_dependencies(${PROJECT} networkextension)
|
||||
|
||||
get_target_property(QtCore_location Qt6::Core LOCATION)
|
||||
message("QtCore_location")
|
||||
message(${QtCore_location})
|
||||
|
||||
get_filename_component(QT_BIN_DIR_DETECTED "${QtCore_location}/../../../../../bin" ABSOLUTE)
|
||||
|
||||
set_property(TARGET ${PROJECT} PROPERTY XCODE_EMBED_FRAMEWORKS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/3rd/OpenVPNAdapter/build/Release-macos/OpenVPNAdapter.framework"
|
||||
)
|
||||
|
||||
set(CMAKE_XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/3rd/OpenVPNAdapter/build/Release-macos)
|
||||
target_link_libraries("networkextension" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/3rd/OpenVPNAdapter/build/Release-macos/OpenVPNAdapter.framework")
|
||||
|
||||
@@ -76,7 +76,7 @@ function(osx_bundle_assetcatalog TARGET)
|
||||
)
|
||||
|
||||
## Patch the asset catalog into the target bundle.
|
||||
if(NOT IOS AND NOT MACOS_NE)
|
||||
if(NOT IOS)
|
||||
set(XCASSETS_RESOURCE_DIR "Resources")
|
||||
endif()
|
||||
add_custom_command(TARGET ${TARGET} POST_BUILD
|
||||
@@ -141,7 +141,6 @@ function(osx_codesign_target TARGET)
|
||||
endif()
|
||||
|
||||
foreach(FILE ${CODESIGN_FILES})
|
||||
message(STATUS "Signing ${TARGET}: ${FILE}")
|
||||
add_custom_command(TARGET ${TARGET} POST_BUILD VERBATIM
|
||||
COMMAND ${COMMENT_ECHO_COMMAND} "Signing ${TARGET}: ${FILE}"
|
||||
COMMAND ${CODESIGN_BIN} ${CODESIGN_ARGS} ${FILE}
|
||||
|
||||
@@ -102,9 +102,7 @@ QProcessEnvironment SshConfigurator::prepareEnv()
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\cygwin;");
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\openvpn;");
|
||||
#elif defined(Q_OS_MACX)
|
||||
#if !defined(MACOS_NE)
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "/Contents/MacOS");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
env.insert("PATH", pathEnvVar);
|
||||
|
||||
@@ -3,38 +3,169 @@
|
||||
#include <QFile>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QUuid>
|
||||
#include "logger.h"
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
#include "core/controllers/serverController.h"
|
||||
#include "core/scripts_registry.h"
|
||||
|
||||
namespace {
|
||||
Logger logger("XrayConfigurator");
|
||||
}
|
||||
|
||||
XrayConfigurator::XrayConfigurator(std::shared_ptr<Settings> settings, const QSharedPointer<ServerController> &serverController, QObject *parent)
|
||||
: ConfiguratorBase(settings, serverController, parent)
|
||||
{
|
||||
}
|
||||
|
||||
QString XrayConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
|
||||
ErrorCode &errorCode)
|
||||
QString XrayConfigurator::prepareServerConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||
const QJsonObject &containerConfig, ErrorCode &errorCode)
|
||||
{
|
||||
QString config = m_serverController->replaceVars(amnezia::scriptData(ProtocolScriptType::xray_template, container),
|
||||
m_serverController->genVarsForScript(credentials, container, containerConfig));
|
||||
|
||||
QString xrayPublicKey =
|
||||
m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::xray::PublicKeyPath, errorCode);
|
||||
xrayPublicKey.replace("\n", "");
|
||||
|
||||
QString xrayUuid = m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::xray::uuidPath, errorCode);
|
||||
xrayUuid.replace("\n", "");
|
||||
|
||||
QString xrayShortId =
|
||||
m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::xray::shortidPath, errorCode);
|
||||
xrayShortId.replace("\n", "");
|
||||
|
||||
// Generate new UUID for client
|
||||
QString clientId = QUuid::createUuid().toString(QUuid::WithoutBraces);
|
||||
|
||||
// Get current server config
|
||||
QString currentConfig = m_serverController->getTextFileFromContainer(
|
||||
container, credentials, amnezia::protocols::xray::serverConfigPath, errorCode);
|
||||
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to get server config file";
|
||||
return "";
|
||||
}
|
||||
|
||||
config.replace("$XRAY_CLIENT_ID", xrayUuid);
|
||||
// Parse current config as JSON
|
||||
QJsonDocument doc = QJsonDocument::fromJson(currentConfig.toUtf8());
|
||||
if (doc.isNull() || !doc.isObject()) {
|
||||
logger.error() << "Failed to parse server config JSON";
|
||||
errorCode = ErrorCode::InternalError;
|
||||
return "";
|
||||
}
|
||||
|
||||
QJsonObject serverConfig = doc.object();
|
||||
|
||||
// Validate server config structure
|
||||
if (!serverConfig.contains("inbounds")) {
|
||||
logger.error() << "Server config missing 'inbounds' field";
|
||||
errorCode = ErrorCode::InternalError;
|
||||
return "";
|
||||
}
|
||||
|
||||
QJsonArray inbounds = serverConfig["inbounds"].toArray();
|
||||
if (inbounds.isEmpty()) {
|
||||
logger.error() << "Server config has empty 'inbounds' array";
|
||||
errorCode = ErrorCode::InternalError;
|
||||
return "";
|
||||
}
|
||||
|
||||
QJsonObject inbound = inbounds[0].toObject();
|
||||
if (!inbound.contains("settings")) {
|
||||
logger.error() << "Inbound missing 'settings' field";
|
||||
errorCode = ErrorCode::InternalError;
|
||||
return "";
|
||||
}
|
||||
|
||||
QJsonObject settings = inbound["settings"].toObject();
|
||||
if (!settings.contains("clients")) {
|
||||
logger.error() << "Settings missing 'clients' field";
|
||||
errorCode = ErrorCode::InternalError;
|
||||
return "";
|
||||
}
|
||||
|
||||
QJsonArray clients = settings["clients"].toArray();
|
||||
|
||||
// Create configuration for new client
|
||||
QJsonObject clientConfig {
|
||||
{"id", clientId},
|
||||
{"flow", "xtls-rprx-vision"}
|
||||
};
|
||||
|
||||
clients.append(clientConfig);
|
||||
|
||||
// Update config
|
||||
settings["clients"] = clients;
|
||||
inbound["settings"] = settings;
|
||||
inbounds[0] = inbound;
|
||||
serverConfig["inbounds"] = inbounds;
|
||||
|
||||
// Save updated config to server
|
||||
QString updatedConfig = QJsonDocument(serverConfig).toJson();
|
||||
errorCode = m_serverController->uploadTextFileToContainer(
|
||||
container,
|
||||
credentials,
|
||||
updatedConfig,
|
||||
amnezia::protocols::xray::serverConfigPath,
|
||||
libssh::ScpOverwriteMode::ScpOverwriteExisting
|
||||
);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to upload updated config";
|
||||
return "";
|
||||
}
|
||||
|
||||
// Restart container
|
||||
QString restartScript = QString("sudo docker restart $CONTAINER_NAME");
|
||||
errorCode = m_serverController->runScript(
|
||||
credentials,
|
||||
m_serverController->replaceVars(restartScript, m_serverController->genVarsForScript(credentials, container))
|
||||
);
|
||||
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to restart container";
|
||||
return "";
|
||||
}
|
||||
|
||||
return clientId;
|
||||
}
|
||||
|
||||
QString XrayConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||
const QJsonObject &containerConfig, ErrorCode &errorCode)
|
||||
{
|
||||
// Get client ID from prepareServerConfig
|
||||
QString xrayClientId = prepareServerConfig(credentials, container, containerConfig, errorCode);
|
||||
if (errorCode != ErrorCode::NoError || xrayClientId.isEmpty()) {
|
||||
logger.error() << "Failed to prepare server config";
|
||||
errorCode = ErrorCode::InternalError;
|
||||
return "";
|
||||
}
|
||||
|
||||
QString config = m_serverController->replaceVars(amnezia::scriptData(ProtocolScriptType::xray_template, container),
|
||||
m_serverController->genVarsForScript(credentials, container, containerConfig));
|
||||
|
||||
if (config.isEmpty()) {
|
||||
logger.error() << "Failed to get config template";
|
||||
errorCode = ErrorCode::InternalError;
|
||||
return "";
|
||||
}
|
||||
|
||||
QString xrayPublicKey =
|
||||
m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::xray::PublicKeyPath, errorCode);
|
||||
if (errorCode != ErrorCode::NoError || xrayPublicKey.isEmpty()) {
|
||||
logger.error() << "Failed to get public key";
|
||||
errorCode = ErrorCode::InternalError;
|
||||
return "";
|
||||
}
|
||||
xrayPublicKey.replace("\n", "");
|
||||
|
||||
QString xrayShortId =
|
||||
m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::xray::shortidPath, errorCode);
|
||||
if (errorCode != ErrorCode::NoError || xrayShortId.isEmpty()) {
|
||||
logger.error() << "Failed to get short ID";
|
||||
errorCode = ErrorCode::InternalError;
|
||||
return "";
|
||||
}
|
||||
xrayShortId.replace("\n", "");
|
||||
|
||||
// Validate all required variables are present
|
||||
if (!config.contains("$XRAY_CLIENT_ID") || !config.contains("$XRAY_PUBLIC_KEY") || !config.contains("$XRAY_SHORT_ID")) {
|
||||
logger.error() << "Config template missing required variables:"
|
||||
<< "XRAY_CLIENT_ID:" << !config.contains("$XRAY_CLIENT_ID")
|
||||
<< "XRAY_PUBLIC_KEY:" << !config.contains("$XRAY_PUBLIC_KEY")
|
||||
<< "XRAY_SHORT_ID:" << !config.contains("$XRAY_SHORT_ID");
|
||||
errorCode = ErrorCode::InternalError;
|
||||
return "";
|
||||
}
|
||||
|
||||
config.replace("$XRAY_CLIENT_ID", xrayClientId);
|
||||
config.replace("$XRAY_PUBLIC_KEY", xrayPublicKey);
|
||||
config.replace("$XRAY_SHORT_ID", xrayShortId);
|
||||
|
||||
|
||||
@@ -14,6 +14,10 @@ public:
|
||||
|
||||
QString createConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
|
||||
ErrorCode &errorCode);
|
||||
|
||||
private:
|
||||
QString prepareServerConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
|
||||
ErrorCode &errorCode);
|
||||
};
|
||||
|
||||
#endif // XRAY_CONFIGURATOR_H
|
||||
|
||||
@@ -50,6 +50,8 @@ namespace
|
||||
constexpr char authData[] = "auth_data";
|
||||
}
|
||||
|
||||
const int requestTimeoutMsecs = 12 * 1000; // 12 secs
|
||||
|
||||
ErrorCode checkErrors(const QList<QSslError> &sslErrors, QNetworkReply *reply)
|
||||
{
|
||||
if (!sslErrors.empty()) {
|
||||
@@ -177,7 +179,7 @@ void ApiController::fillServerConfig(const QString &protocol, const ApiControlle
|
||||
QStringList ApiController::getProxyUrls()
|
||||
{
|
||||
QNetworkRequest request;
|
||||
request.setTransferTimeout(7000);
|
||||
request.setTransferTimeout(requestTimeoutMsecs);
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
|
||||
QEventLoop wait;
|
||||
@@ -280,7 +282,7 @@ void ApiController::updateServerConfigFromApi(const QString &installationUuid, c
|
||||
|
||||
if (serverConfig.value(config_key::configVersion).toInt()) {
|
||||
QNetworkRequest request;
|
||||
request.setTransferTimeout(7000);
|
||||
request.setTransferTimeout(requestTimeoutMsecs);
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
request.setRawHeader("Authorization", "Api-Key " + serverConfig.value(configKey::accessToken).toString().toUtf8());
|
||||
QString endpoint = serverConfig.value(configKey::apiEdnpoint).toString();
|
||||
@@ -336,7 +338,7 @@ ErrorCode ApiController::getServicesList(QByteArray &responseBody)
|
||||
#endif
|
||||
|
||||
QNetworkRequest request;
|
||||
request.setTransferTimeout(7000);
|
||||
request.setTransferTimeout(requestTimeoutMsecs);
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
|
||||
request.setUrl(QString("%1v1/services").arg(m_gatewayEndpoint));
|
||||
@@ -377,6 +379,13 @@ ErrorCode ApiController::getServicesList(QByteArray &responseBody)
|
||||
|
||||
auto errorCode = checkErrors(sslErrors, reply);
|
||||
reply->deleteLater();
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
if (!responseBody.contains("services")) {
|
||||
return ErrorCode::ApiServicesMissingError;
|
||||
}
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
@@ -390,7 +399,7 @@ ErrorCode ApiController::getConfigForService(const QString &installationUuid, co
|
||||
#endif
|
||||
|
||||
QNetworkRequest request;
|
||||
request.setTransferTimeout(7000);
|
||||
request.setTransferTimeout(requestTimeoutMsecs);
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
|
||||
request.setUrl(QString("%1v1/config").arg(m_gatewayEndpoint));
|
||||
|
||||
@@ -109,6 +109,7 @@ namespace amnezia
|
||||
ApiConfigSslError = 1104,
|
||||
ApiMissingAgwPublicKey = 1105,
|
||||
ApiConfigDecryptionError = 1106,
|
||||
ApiServicesMissingError = 1107,
|
||||
|
||||
// QFile errors
|
||||
OpenError = 1200,
|
||||
|
||||
@@ -63,7 +63,8 @@ QString errorString(ErrorCode code) {
|
||||
case (ErrorCode::ApiConfigTimeoutError): errorMessage = QObject::tr("Server response timeout on api request"); break;
|
||||
case (ErrorCode::ApiMissingAgwPublicKey): errorMessage = QObject::tr("Missing AGW public key"); break;
|
||||
case (ErrorCode::ApiConfigDecryptionError): errorMessage = QObject::tr("Failed to decrypt response payload"); break;
|
||||
|
||||
case (ErrorCode::ApiServicesMissingError): errorMessage = QObject::tr("Missing list of available services"); break;
|
||||
|
||||
// QFile errors
|
||||
case(ErrorCode::OpenError): errorMessage = QObject::tr("QFile error: The file could not be opened"); break;
|
||||
case(ErrorCode::ReadError): errorMessage = QObject::tr("QFile error: An error occurred when reading from the file"); break;
|
||||
|
||||
@@ -16,7 +16,5 @@
|
||||
<array>
|
||||
<string>$(AppIdentifierPrefix)group.org.amnezia.AmneziaVPN</string>
|
||||
</array>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 421 B After Width: | Height: | Size: 336 B |
|
Before Width: | Height: | Size: 946 B After Width: | Height: | Size: 593 B |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 946 B After Width: | Height: | Size: 593 B |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 24 KiB |
@@ -1,68 +1,68 @@
|
||||
{
|
||||
"images": [
|
||||
"images" : [
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "16x16",
|
||||
"scale": "1x",
|
||||
"filename": "16.png"
|
||||
"filename" : "16.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "16x16"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "16x16",
|
||||
"scale": "2x",
|
||||
"filename": "16@2x.png"
|
||||
"filename" : "16@2x.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "16x16"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "32x32",
|
||||
"scale": "1x",
|
||||
"filename": "32.png"
|
||||
"filename" : "32.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "32x32"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "32x32",
|
||||
"scale": "2x",
|
||||
"filename": "32@2x.png"
|
||||
"filename" : "32@2x.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "32x32"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "128x128",
|
||||
"scale": "1x",
|
||||
"filename": "128.png"
|
||||
"filename" : "128.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "128x128"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "128x128",
|
||||
"scale": "2x",
|
||||
"filename": "128@2x.png"
|
||||
"filename" : "128@2x.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "128x128"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "256x256",
|
||||
"scale": "1x",
|
||||
"filename": "256.png"
|
||||
"filename" : "256.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "256x256"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "256x256",
|
||||
"scale": "2x",
|
||||
"filename": "256@2x.png"
|
||||
"filename" : "256@2x.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "256x256"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "512x512",
|
||||
"scale": "1x",
|
||||
"filename": "512.png"
|
||||
"filename" : "512.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "512x512"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "512x512",
|
||||
"scale": "2x",
|
||||
"filename": "512@2x.png"
|
||||
"filename" : "512@2x.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "512x512"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"version": 1,
|
||||
"author": "xcode"
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +1,6 @@
|
||||
{
|
||||
"images": [
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "16x16",
|
||||
"scale": "1x",
|
||||
"filename": "16.png"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "16x16",
|
||||
"scale": "2x",
|
||||
"filename": "16@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "32x32",
|
||||
"scale": "1x",
|
||||
"filename": "32.png"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "32x32",
|
||||
"scale": "2x",
|
||||
"filename": "32@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "128x128",
|
||||
"scale": "1x",
|
||||
"filename": "128.png"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "128x128",
|
||||
"scale": "2x",
|
||||
"filename": "128@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "256x256",
|
||||
"scale": "1x",
|
||||
"filename": "256.png"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "256x256",
|
||||
"scale": "2x",
|
||||
"filename": "256@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "512x512",
|
||||
"scale": "1x",
|
||||
"filename": "512.png"
|
||||
},
|
||||
{
|
||||
"idiom": "mac",
|
||||
"size": "512x512",
|
||||
"scale": "2x",
|
||||
"filename": "512@2x.png"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"version": 1,
|
||||
"author": "xcode"
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleAllowMixedLocalizations</key>
|
||||
<true/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>${QT_INTERNAL_DOLLAR_VAR}{PRODUCT_NAME}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.utilities</string>
|
||||
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>AmneziaVPNLaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array/>
|
||||
<key>UIRequiresFullScreen</key>
|
||||
<true/>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array/>
|
||||
<key>UIUserInterfaceStyle</key>
|
||||
<string>Light</string>
|
||||
<key>com.wireguard.ios.app_group_id</key>
|
||||
<string>group.org.amnezia.AmneziaVPN</string>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<true/>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Amnezia VPN needs access to the camera for reading QR-codes.</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<false/>
|
||||
<key>NSAllowsLocalNetworking</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>CFBundleIcons</key>
|
||||
<dict/>
|
||||
<key>CFBundleIcons~ipad</key>
|
||||
<dict/>
|
||||
<key>UTImportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Amnezia VPN config</string>
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.amnezia.AmneziaVPN.amnezia-config</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>vpn</string>
|
||||
</array>
|
||||
<key>public.mime-type</key>
|
||||
<array>
|
||||
<string>text/plain</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>WireGuard config</string>
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.amnezia.AmneziaVPN.wireguard-config</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>conf</string>
|
||||
<string>cfg</string>
|
||||
</array>
|
||||
<key>public.mime-type</key>
|
||||
<array>
|
||||
<string>text/plain</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>OpenVPN config</string>
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.amnezia.AmneziaVPN.openvpn-config</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>ovpn</string>
|
||||
</array>
|
||||
<key>public.mime-type</key>
|
||||
<array>
|
||||
<string>text/plain</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>AmneziaVPN backup file</string>
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.amnezia.AmneziaVPN.backup-config</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>backup</string>
|
||||
</array>
|
||||
<key>public.mime-type</key>
|
||||
<array>
|
||||
<string>text/plain</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Amnezia VPN config</string>
|
||||
<key>LSHandlerRank</key>
|
||||
<string>Alternate</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>org.amnezia.AmneziaVPN.amnezia-config</string>
|
||||
<string>org.amnezia.AmneziaVPN.wireguard-config</string>
|
||||
<string>org.amnezia.AmneziaVPN.openvpn-config</string>
|
||||
<string>org.amnezia.AmneziaVPN.backup-config</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -3,52 +3,40 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.application-identifier</key>
|
||||
<string>X7UJ388FXK.org.amnezia.AmneziaVPN.network-extension</string>
|
||||
<string>$(DEVELOPMENT_TEAM).$(NETEXT_ID_MACOS)</string>
|
||||
|
||||
<key>com.apple.developer.networking.networkextension</key>
|
||||
<array>
|
||||
<string>packet-tunnel-provider</string>
|
||||
</array>
|
||||
<key>com.apple.developer.team-identifier</key>
|
||||
<string>X7UJ388FXK</string>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.org.amnezia.AmneziaVPN</string>
|
||||
</array>
|
||||
<key>com.apple.security.assets.movies.read-write</key>
|
||||
<true/>
|
||||
<key>com.apple.security.assets.music.read-write</key>
|
||||
<true/>
|
||||
<key>com.apple.security.assets.pictures.read-write</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.audio-input</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.bluetooth</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.camera</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.usb</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.downloads.read-write</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.user-selected.read-write</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.server</key>
|
||||
<true/>
|
||||
<key>com.apple.security.personal-information.addressbook</key>
|
||||
<true/>
|
||||
<key>com.apple.security.personal-information.calendars</key>
|
||||
<true/>
|
||||
<key>com.apple.security.personal-information.location</key>
|
||||
<true/>
|
||||
<key>com.apple.security.print</key>
|
||||
<true/>
|
||||
|
||||
<key>keychain-access-groups</key>
|
||||
<array>
|
||||
<string>$(AppIdentifierPrefix)org.amnezia.AmneziaVPN.network-extension</string>
|
||||
<string>$(DEVELOPMENT_TEAM).*</string>
|
||||
</array>
|
||||
|
||||
<key>com.apple.developer.team-identifier</key>
|
||||
<string>$(DEVELOPMENT_TEAM)</string>
|
||||
|
||||
<key>com.apple.developer.system-extension.install</key>
|
||||
<true/>
|
||||
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>$(DEVELOPMENT_TEAM).$(GROUP_ID_MACOS)</string>
|
||||
</array>
|
||||
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
|
||||
<key>com.apple.security.network.server</key>
|
||||
<true/>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.private.network.socket-delegate</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
enable_language(Swift)
|
||||
message("Client message >> macos build >> networkextension")
|
||||
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
|
||||
|
||||
add_executable(networkextension)
|
||||
|
||||
if(MACOS_NE)
|
||||
message("MACOS_NE is ON")
|
||||
add_definitions(-DQ_OS_IOS)
|
||||
add_definitions(-DMACOS_NE)
|
||||
else()
|
||||
message("MACOS_NE is OFF")
|
||||
endif()
|
||||
message("executable_path is: @executable_path/../../Frameworks")
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
XCODE_PRODUCT_TYPE com.apple.product-type.app-extension
|
||||
BUNDLE_EXTENSION appex
|
||||
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${APPLE_PROJECT_VERSION}"
|
||||
MACOSX_BUNDLE_INFO_STRING "AmneziaVPNNetworkExtension"
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "AmneziaVPNNetworkExtension"
|
||||
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${BUILD_IOS_APP_IDENTIFIER}.network-extension"
|
||||
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_NAME "${BUILD_IOS_APP_IDENTIFIER}.network-extension"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${CMAKE_CURRENT_SOURCE_DIR}/AmneziaVPNNetworkExtension.entitlements
|
||||
XCODE_ATTRIBUTE_MARKETING_VERSION "${APP_MAJOR_VERSION}"
|
||||
XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION "${BUILD_ID}"
|
||||
XCODE_ATTRIBUTE_PRODUCT_NAME "AmneziaVPNNetworkExtension"
|
||||
|
||||
XCODE_ATTRIBUTE_APPLICATION_EXTENSION_API_ONLY "YES"
|
||||
XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
|
||||
|
||||
# XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "Mac AppStore AmneziaVPN.network-extension"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "amnezia.AmneziaVPN.network-extensionManual"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution: Privacy Technologies OU (X7UJ388FXK)"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development"
|
||||
|
||||
|
||||
XCODE_ATTRIBUTE_INFOPLIST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in
|
||||
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../../../../Frameworks @loader_path/../../../../Frameworks"
|
||||
)
|
||||
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
|
||||
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES "YES"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/WireGuardNetworkExtension-Bridging-Header.h"
|
||||
XCODE_ATTRIBUTE_SWIFT_OPTIMIZATION_LEVEL "-Onone"
|
||||
XCODE_ATTRIBUTE_SWIFT_PRECOMPILE_BRIDGING_HEADER "NO"
|
||||
)
|
||||
|
||||
set_target_properties("networkextension" PROPERTIES
|
||||
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "X7UJ388FXK"
|
||||
)
|
||||
|
||||
find_library(FW_ASSETS_LIBRARY AssetsLibrary)
|
||||
find_library(FW_MOBILE_CORE MobileCoreServices)
|
||||
find_library(FW_UI_KIT UIKit)
|
||||
find_library(FW_LIBRESOLV libresolv.9.tbd)
|
||||
|
||||
|
||||
# Set the root directory
|
||||
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
|
||||
|
||||
set(CMAKE_FRAMEWORK_PATH ${CLIENT_ROOT_DIR}/3rd/OpenVPNAdapter/build/Release-macos)
|
||||
|
||||
target_link_libraries(networkextension PRIVATE ${FW_LIBRESOLV})
|
||||
|
||||
target_compile_options(networkextension PRIVATE -DGROUP_ID=\"${BUILD_IOS_GROUP_IDENTIFIER}\")
|
||||
target_compile_options(networkextension PRIVATE -DNETWORK_EXTENSION=1)
|
||||
|
||||
set(WG_APPLE_SOURCE_DIR ${CLIENT_ROOT_DIR}/3rd/amneziawg-apple/Sources)
|
||||
|
||||
message("WG_APPLE_SOURCE_DIR is: ${WG_APPLE_SOURCE_DIR}")
|
||||
message("CLIENT_ROOT_DIR is: ${CLIENT_ROOT_DIR}")
|
||||
|
||||
target_sources(networkextension PRIVATE
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/WireGuardAdapter.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PacketTunnelSettingsGenerator.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/DNSResolver.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardNetworkExtension/ErrorNotifier.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/Keychain.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/Model/TunnelConfiguration+WgQuickConfig.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/Model/NETunnelProviderProtocol+Extension.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/Model/String+ArrayConversion.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/TunnelConfiguration.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/IPAddressRange.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/Endpoint.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/DNSServer.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/InterfaceConfiguration.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PeerConfiguration.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/FileManager+Extension.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKitC/x25519.c
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/Array+ConcurrentMap.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/IPAddress+AddrInfo.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PrivateKey.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/HevSocksTunnel.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/NELogController.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/Log.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/LogRecord.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+WireGuard.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+OpenVPN.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+Xray.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/WGConfig.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/iosglue.mm
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/XrayConfig.swift
|
||||
)
|
||||
|
||||
target_sources(networkextension PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
set_property(TARGET networkextension APPEND PROPERTY RESOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
## Build wireguard-go-version.h
|
||||
execute_process(
|
||||
COMMAND go list -m golang.zx2c4.com/wireguard
|
||||
WORKING_DIRECTORY ${CLIENT_ROOT_DIR}/3rd/wireguard-apple/Sources/WireGuardKitGo
|
||||
OUTPUT_VARIABLE WG_VERSION_FULL
|
||||
)
|
||||
string(REGEX REPLACE ".*v\([0-9.]*\).*" "\\1" WG_VERSION_STRING 1.1.1)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/wireguard-go-version.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h)
|
||||
target_sources(networkextension PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h)
|
||||
|
||||
target_include_directories(networkextension PRIVATE ${CLIENT_ROOT_DIR})
|
||||
target_include_directories(networkextension PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
target_link_libraries(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/wireguard/macos/x86_64/libwg-go.a)
|
||||
|
||||
message(${CLIENT_ROOT_DIR})
|
||||
message(${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/libhev-socks5-tunnel.a)
|
||||
target_link_libraries(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/libhev-socks5-tunnel.a)
|
||||
|
||||
target_include_directories(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/Headers)
|
||||
@@ -3,32 +3,27 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>AmneziaVPNNetworkExtension</string>
|
||||
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.amnezia.AmneziaVPN.network-extension</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>AmneziaVPNNetworkExtension</string>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${APPLE_PROJECT_VERSION}</string>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${CMAKE_PROJECT_VERSION_TWEAK}</string>
|
||||
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
|
||||
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>AmneziaVPNNetworkExtension</string>
|
||||
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
@@ -36,11 +31,5 @@
|
||||
<key>NSExtensionPrincipalClass</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).PacketTunnelProvider</string>
|
||||
</dict>
|
||||
|
||||
<key>com.wireguard.ios.app_group_id</key>
|
||||
<string>group.org.amnezia.AmneziaVPN</string>
|
||||
|
||||
<key>com.wireguard.macos.app_group_id</key>
|
||||
<string>${BUILD_VPN_DEVELOPMENT_TEAM}.group.org.amnezia.AmneziaVPN</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>1C8F.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>C617.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,10 +1,10 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
#include "macos/gobridge/wireguard.h"
|
||||
#include "wireguard-go-version.h"
|
||||
#include "3rd/amneziawg-apple/Sources/WireGuardKitGo/wireguard.h"
|
||||
#include "3rd/amneziawg-apple/Sources/WireGuardKitC/WireGuardKitC.h"
|
||||
#include "3rd/awg-apple/Sources/WireGuardKitC/WireGuardKitC.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
@@ -23,8 +23,3 @@ bool key_from_hex(uint8_t key[WG_KEY_LEN], const char* hex);
|
||||
bool key_eq(const uint8_t key1[WG_KEY_LEN], const uint8_t key2[WG_KEY_LEN]);
|
||||
|
||||
void write_msg_to_log(const char* tag, const char* msg);
|
||||
|
||||
// init function definition in C
|
||||
void hev_socks5_tunnel_quit(void);
|
||||
// Updated function definition in C
|
||||
int hev_socks5_tunnel_main(const char* configFile, int fd);
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#ifndef WIREGUARD_GO_VERSION
|
||||
#define WIREGUARD_GO_VERSION "@WG_VERSION_STRING@"
|
||||
#endif // WIREGUARD_GO_VERSION
|
||||
@@ -1,36 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
XCODEBUILD="/usr/bin/xcodebuild"
|
||||
WORKINGDIR=`pwd`
|
||||
PATCH="/usr/bin/patch"
|
||||
|
||||
echo "Building OpenVPNAdapter for macOS Network Extension (MacNE)..."
|
||||
|
||||
# Copy the Project-MacNE.xcconfig settings to amnezia.xcconfig
|
||||
cat $WORKINGDIR/3rd/OpenVPNAdapter/Configuration/Project-MacNE.xcconfig > $WORKINGDIR/3rd/OpenVPNAdapter/Configuration/amnezia.xcconfig
|
||||
|
||||
# Append macOS-specific build directory configurations to amnezia.xcconfig
|
||||
cat << EOF >> $WORKINGDIR/3rd/OpenVPNAdapter/Configuration/amnezia.xcconfig
|
||||
PROJECT_TEMP_DIR = $WORKINGDIR/3rd/OpenVPNAdapter/build/OpenVPNAdapter.build
|
||||
CONFIGURATION_BUILD_DIR = $WORKINGDIR/3rd/OpenVPNAdapter/build/Release-macos
|
||||
BUILT_PRODUCTS_DIR = $WORKINGDIR/3rd/OpenVPNAdapter/build/Release-macos
|
||||
EOF
|
||||
|
||||
# Fetch the current macOS SDK version dynamically
|
||||
MACOSX_SDK=$(xcrun --sdk macosx --show-sdk-path | sed -E 's/.*MacOSX([0-9]+\.[0-9]+)\.sdk/\1/')
|
||||
|
||||
echo "Using macOS SDK version: $MACOSX_SDK"
|
||||
|
||||
cd 3rd/OpenVPNAdapter
|
||||
|
||||
# Build for macOS using the correct SDK and destination
|
||||
if $XCODEBUILD -scheme OpenVPNAdapter -configuration Release -xcconfig Configuration/amnezia.xcconfig -sdk macosx$MACOSX_SDK -destination 'generic/platform=macOS' -project OpenVPNAdapter.xcodeproj ; then
|
||||
echo "OpenVPNAdapter built successfully for macOS Network Extension (MacNE)"
|
||||
else
|
||||
echo "OpenVPNAdapter macOS Network Extension (MacNE) build failed..."
|
||||
fi
|
||||
|
||||
# Remove CodeSignature if needed for macOS
|
||||
rm -rf ./build/Release-macos/OpenVPNAdapter.framework/Versions/A/_CodeSignature
|
||||
|
||||
cd ../../
|
||||
@@ -163,9 +163,7 @@ QString AndroidController::openFile(const QString &filter)
|
||||
QString fileName;
|
||||
connect(this, &AndroidController::fileOpened, this,
|
||||
[&fileName, &wait](const QString &uri) {
|
||||
qDebug() << "Android event: file opened; uri:" << uri;
|
||||
fileName = QQmlFile::urlToLocalFileOrQrc(uri);
|
||||
qDebug() << "Android opened filename:" << fileName;
|
||||
fileName = uri;
|
||||
wait.quit();
|
||||
},
|
||||
static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::SingleShotConnection));
|
||||
@@ -175,6 +173,25 @@ QString AndroidController::openFile(const QString &filter)
|
||||
return fileName;
|
||||
}
|
||||
|
||||
int AndroidController::getFd(const QString &fileName)
|
||||
{
|
||||
return callActivityMethod<jint>("getFd", "(Ljava/lang/String;)I",
|
||||
QJniObject::fromString(fileName).object<jstring>());
|
||||
}
|
||||
|
||||
void AndroidController::closeFd()
|
||||
{
|
||||
callActivityMethod("closeFd", "()V");
|
||||
}
|
||||
|
||||
QString AndroidController::getFileName(const QString &uri)
|
||||
{
|
||||
auto fileName = callActivityMethod<jstring, jstring>("getFileName", "(Ljava/lang/String;)Ljava/lang/String;",
|
||||
QJniObject::fromString(uri).object<jstring>());
|
||||
QJniEnvironment env;
|
||||
return AndroidUtils::convertJString(env.jniEnv(), fileName.object<jstring>());
|
||||
}
|
||||
|
||||
bool AndroidController::isCameraPresent()
|
||||
{
|
||||
return callActivityMethod<jboolean>("isCameraPresent", "()Z");
|
||||
@@ -287,6 +304,11 @@ bool AndroidController::requestAuthentication()
|
||||
return result;
|
||||
}
|
||||
|
||||
void AndroidController::sendTouch(float x, float y)
|
||||
{
|
||||
callActivityMethod("sendTouch", "(FF)V", x, y);
|
||||
}
|
||||
|
||||
// Moving log processing to the Android side
|
||||
jclass AndroidController::log;
|
||||
jmethodID AndroidController::logDebug;
|
||||
|
||||
@@ -34,6 +34,9 @@ public:
|
||||
void resetLastServer(int serverIndex);
|
||||
void saveFile(const QString &fileName, const QString &data);
|
||||
QString openFile(const QString &filter);
|
||||
int getFd(const QString &fileName);
|
||||
void closeFd();
|
||||
QString getFileName(const QString &uri);
|
||||
bool isCameraPresent();
|
||||
bool isOnTv();
|
||||
void startQrReaderActivity();
|
||||
@@ -48,6 +51,7 @@ public:
|
||||
bool isNotificationPermissionGranted();
|
||||
void requestNotificationPermission();
|
||||
bool requestAuthentication();
|
||||
void sendTouch(float x, float y);
|
||||
|
||||
static bool initLogging();
|
||||
static void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &message);
|
||||
|
||||
@@ -47,7 +47,7 @@ extension PacketTunnelProvider {
|
||||
let configuration = OpenVPNConfiguration()
|
||||
configuration.fileContent = ovpnConfiguration
|
||||
if str.contains("cloak") {
|
||||
configuration.setPTCloak()
|
||||
configuration.setPTCloak()
|
||||
}
|
||||
|
||||
let evaluation: OpenVPNConfigurationEvaluation?
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#if !MACOS_NE
|
||||
#include "QRCodeReaderBase.h"
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
@@ -109,19 +108,3 @@ void QRCodeReader::startReading() {
|
||||
void QRCodeReader::stopReading() {
|
||||
[m_qrCodeReader stopReading];
|
||||
}
|
||||
#else
|
||||
#include "QRCodeReaderBase.h"
|
||||
|
||||
QRCodeReader::QRCodeReader()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QRect QRCodeReader::cameraSize() {
|
||||
return QRect();
|
||||
}
|
||||
|
||||
void QRCodeReader::startReading() {}
|
||||
void QRCodeReader::stopReading() {}
|
||||
void QRCodeReader::setCameraSize(QRect) {}
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#if !MACOS_NE
|
||||
#import <UIKit/UIKit.h>
|
||||
#endif
|
||||
|
||||
@interface QIOSApplicationDelegate
|
||||
@end
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
|
||||
@implementation QIOSApplicationDelegate (AmneziaVPNDelegate)
|
||||
#if !MACOS_NE
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
[application setMinimumBackgroundFetchInterval: UIApplicationBackgroundFetchIntervalMinimum];
|
||||
@@ -57,5 +57,5 @@
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,13 +1,3 @@
|
||||
#if MACOS_NE
|
||||
public func toggleScreenshots(_ isEnabled: Bool) {
|
||||
|
||||
}
|
||||
|
||||
class ScreenProtection {
|
||||
|
||||
|
||||
}
|
||||
#else
|
||||
import UIKit
|
||||
|
||||
public func toggleScreenshots(_ isEnabled: Bool) {
|
||||
@@ -95,4 +85,3 @@ struct ProtectionPair {
|
||||
textField.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -27,7 +27,6 @@ const char* MessageKey::isOnDemand = "is-on-demand";
|
||||
const char* MessageKey::SplitTunnelType = "SplitTunnelType";
|
||||
const char* MessageKey::SplitTunnelSites = "SplitTunnelSites";
|
||||
|
||||
#if !MACOS_NE
|
||||
static UIViewController* getViewController() {
|
||||
NSArray *windows = [[UIApplication sharedApplication]windows];
|
||||
for (UIWindow *window in windows) {
|
||||
@@ -37,7 +36,6 @@ static UIViewController* getViewController() {
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
#endif
|
||||
|
||||
Vpn::ConnectionState iosStatusToState(NEVPNStatus status) {
|
||||
switch (status) {
|
||||
@@ -791,14 +789,14 @@ bool IosController::shareText(const QStringList& filesToSend) {
|
||||
NSURL *logFileUrl = [[NSURL alloc] initFileURLWithPath:filesToSend[i].toNSString()];
|
||||
[sharingItems addObject:logFileUrl];
|
||||
}
|
||||
#if !MACOS_NE
|
||||
|
||||
UIViewController *qtController = getViewController();
|
||||
if (!qtController) return;
|
||||
|
||||
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:sharingItems applicationActivities:nil];
|
||||
#endif
|
||||
|
||||
__block bool isAccepted = false;
|
||||
#if !MACOS_NE
|
||||
|
||||
[activityController setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
|
||||
isAccepted = completed;
|
||||
emit finished();
|
||||
@@ -810,7 +808,7 @@ bool IosController::shareText(const QStringList& filesToSend) {
|
||||
popController.sourceView = qtController.view;
|
||||
popController.sourceRect = CGRectMake(100, 100, 100, 100);
|
||||
}
|
||||
#endif
|
||||
|
||||
QEventLoop wait;
|
||||
QObject::connect(this, &IosController::finished, &wait, &QEventLoop::quit);
|
||||
wait.exec();
|
||||
@@ -819,7 +817,6 @@ bool IosController::shareText(const QStringList& filesToSend) {
|
||||
}
|
||||
|
||||
QString IosController::openFile() {
|
||||
#if !MACOS_NE
|
||||
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[@"public.item"] inMode:UIDocumentPickerModeOpen];
|
||||
|
||||
DocumentPickerDelegate *documentPickerDelegate = [[DocumentPickerDelegate alloc] init];
|
||||
@@ -829,9 +826,9 @@ QString IosController::openFile() {
|
||||
if (!qtController) return;
|
||||
|
||||
[qtController presentViewController:documentPicker animated:YES completion:nil];
|
||||
#endif
|
||||
|
||||
__block QString filePath;
|
||||
#if !MACOS_NE
|
||||
|
||||
documentPickerDelegate.documentPickerClosedCallback = ^(NSString *path) {
|
||||
if (path) {
|
||||
filePath = QString::fromUtf8(path.UTF8String);
|
||||
@@ -840,7 +837,7 @@ QString IosController::openFile() {
|
||||
}
|
||||
emit finished();
|
||||
};
|
||||
#endif
|
||||
|
||||
QEventLoop wait;
|
||||
QObject::connect(this, &IosController::finished, &wait, &QEventLoop::quit);
|
||||
wait.exec();
|
||||
@@ -866,4 +863,3 @@ void IosController::requestInetAccess() {
|
||||
}];
|
||||
[task resume];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
#import <NetworkExtension/NetworkExtension.h>
|
||||
#import <NetworkExtension/NETunnelProviderSession.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if !MACOS_NE
|
||||
#include <UIKit/UIKit.h>
|
||||
#endif
|
||||
|
||||
#include <Security/Security.h>
|
||||
|
||||
class IosController;
|
||||
@@ -21,10 +17,9 @@ class IosController;
|
||||
@end
|
||||
|
||||
typedef void (^DocumentPickerClosedCallback)(NSString *path);
|
||||
#if !MACOS_NE
|
||||
|
||||
@interface DocumentPickerDelegate : NSObject <UIDocumentPickerDelegate>
|
||||
|
||||
@property (nonatomic, copy) DocumentPickerClosedCallback documentPickerClosedCallback;
|
||||
|
||||
@end
|
||||
#endif
|
||||
|
||||
@@ -26,8 +26,7 @@
|
||||
|
||||
@end
|
||||
|
||||
#if !MACOS_NE
|
||||
@implementation DocumentPickerDelegate
|
||||
@implementation DocumentPickerDelegate
|
||||
|
||||
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {
|
||||
for (NSURL *url in urls) {
|
||||
@@ -43,5 +42,4 @@
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
#endif
|
||||
@end
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
#import <UserNotifications/UserNotifications.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if !MACOS_NE
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface IOSNotificationDelegate
|
||||
@@ -89,86 +87,3 @@ void IOSNotificationHandler::notify(NotificationHandler::Message type, const QSt
|
||||
}
|
||||
}];
|
||||
}
|
||||
#else
|
||||
|
||||
// Removed the UIResponder and UIApplicationDelegate references as these are not available in macOS
|
||||
@interface IOSNotificationDelegate
|
||||
: NSObject <UNUserNotificationCenterDelegate> {
|
||||
IOSNotificationHandler* m_iosNotificationHandler;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation IOSNotificationDelegate
|
||||
|
||||
- (id)initWithObject:(IOSNotificationHandler*)notification {
|
||||
self = [super init]; // Removed `super init` as it refers to UIResponder, which is iOS specific
|
||||
if (self) {
|
||||
m_iosNotificationHandler = notification;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)userNotificationCenter:(UNUserNotificationCenter*)center
|
||||
willPresentNotification:(UNNotification*)notification
|
||||
withCompletionHandler:
|
||||
(void (^)(UNNotificationPresentationOptions options))completionHandler {
|
||||
Q_UNUSED(center)
|
||||
completionHandler(UNNotificationPresentationOptionList | UNNotificationPresentationOptionBanner);
|
||||
}
|
||||
|
||||
- (void)userNotificationCenter:(UNUserNotificationCenter*)center
|
||||
didReceiveNotificationResponse:(UNNotificationResponse*)response
|
||||
withCompletionHandler:(void (^)())completionHandler {
|
||||
Q_UNUSED(center)
|
||||
Q_UNUSED(response)
|
||||
completionHandler();
|
||||
}
|
||||
@end
|
||||
|
||||
IOSNotificationHandler::IOSNotificationHandler(QObject* parent) : NotificationHandler(parent) {
|
||||
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert |
|
||||
UNAuthorizationOptionBadge)
|
||||
completionHandler:^(BOOL granted, NSError* _Nullable error) {
|
||||
Q_UNUSED(granted);
|
||||
if (!error) {
|
||||
m_delegate = [[IOSNotificationDelegate alloc] initWithObject:this];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
IOSNotificationHandler::~IOSNotificationHandler() { }
|
||||
|
||||
void IOSNotificationHandler::notify(NotificationHandler::Message type, const QString& title,
|
||||
const QString& message, int timerMsec) {
|
||||
Q_UNUSED(type);
|
||||
|
||||
if (!m_delegate) {
|
||||
return;
|
||||
}
|
||||
|
||||
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
|
||||
content.title = title.toNSString();
|
||||
content.body = message.toNSString();
|
||||
content.sound = [UNNotificationSound defaultSound];
|
||||
|
||||
int timerSec = timerMsec / 1000;
|
||||
UNTimeIntervalNotificationTrigger* trigger =
|
||||
[UNTimeIntervalNotificationTrigger triggerWithTimeInterval:timerSec repeats:NO];
|
||||
|
||||
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"amneziavpn"
|
||||
content:content
|
||||
trigger:trigger];
|
||||
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
center.delegate = (id<UNUserNotificationCenterDelegate>)m_delegate;
|
||||
|
||||
[center addNotificationRequest:request
|
||||
withCompletionHandler:^(NSError* _Nullable error) {
|
||||
if (error) {
|
||||
NSLog(@"Local Notification failed");
|
||||
}
|
||||
}];
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "core/errorstrings.h"
|
||||
#include "vpnprotocol.h"
|
||||
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) and !defined MACOS_NE || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
#include "openvpnovercloakprotocol.h"
|
||||
#include "openvpnprotocol.h"
|
||||
#include "shadowsocksvpnprotocol.h"
|
||||
@@ -109,7 +109,7 @@ VpnProtocol *VpnProtocol::factory(DockerContainer container, const QJsonObject &
|
||||
#if defined(Q_OS_WINDOWS)
|
||||
case DockerContainer::Ipsec: return new Ikev2Protocol(configuration);
|
||||
#endif
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) and !defined MACOS_NE || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
case DockerContainer::OpenVpn: return new OpenVpnProtocol(configuration);
|
||||
case DockerContainer::Cloak: return new OpenVpnOverCloakProtocol(configuration);
|
||||
case DockerContainer::ShadowSocks: return new ShadowSocksVpnProtocol(configuration);
|
||||
|
||||
@@ -1,225 +1,227 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>fonts/pt-root-ui_vf.ttf</file>
|
||||
<file>images/amneziaBigLogo.png</file>
|
||||
<file>images/AmneziaVPN.png</file>
|
||||
<file>images/controls/alert-circle.svg</file>
|
||||
<file>images/controls/amnezia.svg</file>
|
||||
<file>images/controls/app.svg</file>
|
||||
<file>images/controls/archive-restore.svg</file>
|
||||
<file>images/controls/arrow-left.svg</file>
|
||||
<file>images/controls/arrow-right.svg</file>
|
||||
<file>images/controls/bug.svg</file>
|
||||
<file>images/controls/check.svg</file>
|
||||
<file>images/controls/chevron-down.svg</file>
|
||||
<file>images/controls/chevron-right.svg</file>
|
||||
<file>images/controls/chevron-up.svg</file>
|
||||
<file>images/controls/close.svg</file>
|
||||
<file>images/controls/copy.svg</file>
|
||||
<file>images/controls/delete.svg</file>
|
||||
<file>images/controls/download.svg</file>
|
||||
<file>images/controls/edit-3.svg</file>
|
||||
<file>images/controls/eye-off.svg</file>
|
||||
<file>images/controls/eye.svg</file>
|
||||
<file>images/controls/file-check-2.svg</file>
|
||||
<file>images/controls/file-cog-2.svg</file>
|
||||
<file>images/controls/folder-open.svg</file>
|
||||
<file>images/controls/folder-search-2.svg</file>
|
||||
<file>images/controls/gauge.svg</file>
|
||||
<file>images/controls/github.svg</file>
|
||||
<file>images/controls/help-circle.svg</file>
|
||||
<file>images/controls/history.svg</file>
|
||||
<file>images/controls/home.svg</file>
|
||||
<file>images/controls/info.svg</file>
|
||||
<file>images/controls/mail.svg</file>
|
||||
<file>images/controls/map-pin.svg</file>
|
||||
<file>images/controls/more-vertical.svg</file>
|
||||
<file>images/controls/plus.svg</file>
|
||||
<file>images/controls/qr-code.svg</file>
|
||||
<file>images/controls/radio-button-inner-circle-pressed.png</file>
|
||||
<file>images/controls/radio-button-inner-circle.png</file>
|
||||
<file>images/controls/radio-button-pressed.svg</file>
|
||||
<file>images/controls/radio-button.svg</file>
|
||||
<file>images/controls/radio.svg</file>
|
||||
<file>images/controls/refresh-cw.svg</file>
|
||||
<file>images/controls/save.svg</file>
|
||||
<file>images/controls/scan-line.svg</file>
|
||||
<file>images/controls/search.svg</file>
|
||||
<file>images/controls/server.svg</file>
|
||||
<file>images/controls/settings-2.svg</file>
|
||||
<file>images/controls/settings.svg</file>
|
||||
<file>images/controls/share-2.svg</file>
|
||||
<file>images/controls/split-tunneling.svg</file>
|
||||
<file>images/controls/tag.svg</file>
|
||||
<file>images/controls/telegram.svg</file>
|
||||
<file>images/controls/text-cursor.svg</file>
|
||||
<file>images/controls/trash.svg</file>
|
||||
<file>images/controls/x-circle.svg</file>
|
||||
<file>images/tray/active.png</file>
|
||||
<file>images/tray/default.png</file>
|
||||
<file>images/tray/error.png</file>
|
||||
<file>images/AmneziaVPN.png</file>
|
||||
<file>server_scripts/remove_container.sh</file>
|
||||
<file>server_scripts/setup_host_firewall.sh</file>
|
||||
<file>server_scripts/openvpn_cloak/Dockerfile</file>
|
||||
<file>server_scripts/awg/configure_container.sh</file>
|
||||
<file>server_scripts/awg/Dockerfile</file>
|
||||
<file>server_scripts/awg/run_container.sh</file>
|
||||
<file>server_scripts/awg/start.sh</file>
|
||||
<file>server_scripts/awg/template.conf</file>
|
||||
<file>server_scripts/build_container.sh</file>
|
||||
<file>server_scripts/check_connection.sh</file>
|
||||
<file>server_scripts/check_server_is_busy.sh</file>
|
||||
<file>server_scripts/check_user_in_sudo.sh</file>
|
||||
<file>server_scripts/dns/configure_container.sh</file>
|
||||
<file>server_scripts/dns/Dockerfile</file>
|
||||
<file>server_scripts/dns/run_container.sh</file>
|
||||
<file>server_scripts/install_docker.sh</file>
|
||||
<file>server_scripts/ipsec/configure_container.sh</file>
|
||||
<file>server_scripts/ipsec/Dockerfile</file>
|
||||
<file>server_scripts/ipsec/mobileconfig.plist</file>
|
||||
<file>server_scripts/ipsec/run_container.sh</file>
|
||||
<file>server_scripts/ipsec/start.sh</file>
|
||||
<file>server_scripts/ipsec/strongswan.profile</file>
|
||||
<file>server_scripts/openvpn_cloak/configure_container.sh</file>
|
||||
<file>server_scripts/openvpn_cloak/Dockerfile</file>
|
||||
<file>server_scripts/openvpn_cloak/run_container.sh</file>
|
||||
<file>server_scripts/openvpn_cloak/start.sh</file>
|
||||
<file>server_scripts/openvpn_cloak/template.ovpn</file>
|
||||
<file>server_scripts/install_docker.sh</file>
|
||||
<file>server_scripts/build_container.sh</file>
|
||||
<file>server_scripts/prepare_host.sh</file>
|
||||
<file>server_scripts/check_connection.sh</file>
|
||||
<file>server_scripts/remove_all_containers.sh</file>
|
||||
<file>server_scripts/openvpn_cloak/run_container.sh</file>
|
||||
<file>server_scripts/openvpn/configure_container.sh</file>
|
||||
<file>server_scripts/openvpn/run_container.sh</file>
|
||||
<file>server_scripts/openvpn/template.ovpn</file>
|
||||
<file>server_scripts/openvpn/Dockerfile</file>
|
||||
<file>server_scripts/openvpn/start.sh</file>
|
||||
<file>server_scripts/openvpn_shadowsocks/configure_container.sh</file>
|
||||
<file>server_scripts/openvpn_shadowsocks/Dockerfile</file>
|
||||
<file>server_scripts/openvpn_shadowsocks/run_container.sh</file>
|
||||
<file>server_scripts/openvpn_shadowsocks/start.sh</file>
|
||||
<file>server_scripts/openvpn_shadowsocks/template.ovpn</file>
|
||||
<file>server_scripts/openvpn/configure_container.sh</file>
|
||||
<file>server_scripts/openvpn/Dockerfile</file>
|
||||
<file>server_scripts/openvpn/run_container.sh</file>
|
||||
<file>server_scripts/openvpn/start.sh</file>
|
||||
<file>server_scripts/openvpn/template.ovpn</file>
|
||||
<file>server_scripts/prepare_host.sh</file>
|
||||
<file>server_scripts/remove_all_containers.sh</file>
|
||||
<file>server_scripts/remove_container.sh</file>
|
||||
<file>server_scripts/setup_host_firewall.sh</file>
|
||||
<file>server_scripts/sftp/configure_container.sh</file>
|
||||
<file>server_scripts/sftp/Dockerfile</file>
|
||||
<file>server_scripts/sftp/run_container.sh</file>
|
||||
<file>server_scripts/socks5_proxy/configure_container.sh</file>
|
||||
<file>server_scripts/socks5_proxy/Dockerfile</file>
|
||||
<file>server_scripts/socks5_proxy/run_container.sh</file>
|
||||
<file>server_scripts/socks5_proxy/start.sh</file>
|
||||
<file>server_scripts/website_tor/configure_container.sh</file>
|
||||
<file>server_scripts/website_tor/Dockerfile</file>
|
||||
<file>server_scripts/website_tor/run_container.sh</file>
|
||||
<file>server_scripts/wireguard/configure_container.sh</file>
|
||||
<file>server_scripts/wireguard/Dockerfile</file>
|
||||
<file>server_scripts/wireguard/run_container.sh</file>
|
||||
<file>server_scripts/wireguard/start.sh</file>
|
||||
<file>server_scripts/wireguard/template.conf</file>
|
||||
<file>server_scripts/website_tor/configure_container.sh</file>
|
||||
<file>server_scripts/website_tor/run_container.sh</file>
|
||||
<file>ui/qml/Config/GlobalConfig.qml</file>
|
||||
<file>ui/qml/Config/qmldir</file>
|
||||
<file>server_scripts/check_server_is_busy.sh</file>
|
||||
<file>server_scripts/dns/configure_container.sh</file>
|
||||
<file>server_scripts/dns/Dockerfile</file>
|
||||
<file>server_scripts/dns/run_container.sh</file>
|
||||
<file>server_scripts/sftp/configure_container.sh</file>
|
||||
<file>server_scripts/sftp/Dockerfile</file>
|
||||
<file>server_scripts/sftp/run_container.sh</file>
|
||||
<file>server_scripts/ipsec/configure_container.sh</file>
|
||||
<file>server_scripts/ipsec/Dockerfile</file>
|
||||
<file>server_scripts/ipsec/run_container.sh</file>
|
||||
<file>server_scripts/ipsec/start.sh</file>
|
||||
<file>server_scripts/ipsec/mobileconfig.plist</file>
|
||||
<file>server_scripts/ipsec/strongswan.profile</file>
|
||||
<file>server_scripts/website_tor/Dockerfile</file>
|
||||
<file>server_scripts/check_user_in_sudo.sh</file>
|
||||
<file>ui/qml/Controls2/BasicButtonType.qml</file>
|
||||
<file>ui/qml/Controls2/TextFieldWithHeaderType.qml</file>
|
||||
<file>ui/qml/Controls2/LabelWithButtonType.qml</file>
|
||||
<file>images/controls/arrow-right.svg</file>
|
||||
<file>images/controls/chevron-right.svg</file>
|
||||
<file>ui/qml/Controls2/ImageButtonType.qml</file>
|
||||
<file>ui/qml/Controls2/CardType.qml</file>
|
||||
<file>ui/qml/Controls2/CheckBoxType.qml</file>
|
||||
<file>images/controls/check.svg</file>
|
||||
<file>ui/qml/Controls2/DropDownType.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardStart.qml</file>
|
||||
<file>ui/qml/main2.qml</file>
|
||||
<file>images/amneziaBigLogo.png</file>
|
||||
<file>ui/qml/Controls2/FlickableType.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardCredentials.qml</file>
|
||||
<file>ui/qml/Controls2/HeaderType.qml</file>
|
||||
<file>images/controls/arrow-left.svg</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardProtocols.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardEasy.qml</file>
|
||||
<file>images/controls/chevron-down.svg</file>
|
||||
<file>images/controls/chevron-up.svg</file>
|
||||
<file>ui/qml/Controls2/TextTypes/ParagraphTextType.qml</file>
|
||||
<file>ui/qml/Controls2/TextTypes/Header2TextType.qml</file>
|
||||
<file>ui/qml/Controls2/HorizontalRadioButton.qml</file>
|
||||
<file>ui/qml/Controls2/VerticalRadioButton.qml</file>
|
||||
<file>ui/qml/Controls2/SwitcherType.qml</file>
|
||||
<file>ui/qml/Controls2/TabButtonType.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardProtocolSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardInstalling.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardConfigSource.qml</file>
|
||||
<file>images/controls/folder-open.svg</file>
|
||||
<file>images/controls/qr-code.svg</file>
|
||||
<file>images/controls/text-cursor.svg</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardTextKey.qml</file>
|
||||
<file>ui/qml/Pages2/PageStart.qml</file>
|
||||
<file>ui/qml/Controls2/TabImageButtonType.qml</file>
|
||||
<file>images/controls/home.svg</file>
|
||||
<file>images/controls/settings-2.svg</file>
|
||||
<file>images/controls/share-2.svg</file>
|
||||
<file>ui/qml/Pages2/PageHome.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsServersList.qml</file>
|
||||
<file>ui/qml/Pages2/PageShare.qml</file>
|
||||
<file>ui/qml/Controls2/TextTypes/Header1TextType.qml</file>
|
||||
<file>ui/qml/Controls2/TextTypes/LabelTextType.qml</file>
|
||||
<file>ui/qml/Controls2/TextTypes/ButtonTextType.qml</file>
|
||||
<file>ui/qml/Controls2/Header2Type.qml</file>
|
||||
<file>images/controls/plus.svg</file>
|
||||
<file>ui/qml/Components/ConnectButton.qml</file>
|
||||
<file>images/controls/download.svg</file>
|
||||
<file>ui/qml/Controls2/ProgressBarType.qml</file>
|
||||
<file>ui/qml/Components/ConnectionTypeSelectionDrawer.qml</file>
|
||||
<file>ui/qml/Components/HomeContainersListView.qml</file>
|
||||
<file>ui/qml/Controls2/TextTypes/CaptionTextType.qml</file>
|
||||
<file>images/controls/settings.svg</file>
|
||||
<file>ui/qml/Pages2/PageSettingsServerInfo.qml</file>
|
||||
<file>ui/qml/Controls2/PageType.qml</file>
|
||||
<file>ui/qml/Controls2/PopupType.qml</file>
|
||||
<file>images/controls/edit-3.svg</file>
|
||||
<file>ui/qml/Pages2/PageSettingsServerData.qml</file>
|
||||
<file>ui/qml/Components/SettingsContainersListView.qml</file>
|
||||
<file>ui/qml/Controls2/TextTypes/ListItemTitleType.qml</file>
|
||||
<file>ui/qml/Controls2/DividerType.qml</file>
|
||||
<file>ui/qml/Controls2/StackViewType.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettings.qml</file>
|
||||
<file>images/controls/amnezia.svg</file>
|
||||
<file>images/controls/app.svg</file>
|
||||
<file>images/controls/radio.svg</file>
|
||||
<file>images/controls/save.svg</file>
|
||||
<file>images/controls/server.svg</file>
|
||||
<file>ui/qml/Pages2/PageSettingsServerProtocols.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsServerServices.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardViewConfig.qml</file>
|
||||
<file>images/controls/file-cog-2.svg</file>
|
||||
<file>ui/qml/Components/QuestionDrawer.qml</file>
|
||||
<file>ui/qml/Pages2/PageDeinstalling.qml</file>
|
||||
<file>ui/qml/Controls2/BackButtonType.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsServerProtocol.qml</file>
|
||||
<file>ui/qml/Components/TransportProtoSelector.qml</file>
|
||||
<file>ui/qml/Controls2/ListViewWithRadioButtonType.qml</file>
|
||||
<file>images/controls/radio-button.svg</file>
|
||||
<file>images/controls/radio-button-inner-circle.png</file>
|
||||
<file>images/controls/radio-button-pressed.svg</file>
|
||||
<file>images/controls/radio-button-inner-circle-pressed.png</file>
|
||||
<file>ui/qml/Components/ShareConnectionDrawer.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsConnection.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsDns.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsApplication.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsBackup.qml</file>
|
||||
<file>images/controls/delete.svg</file>
|
||||
<file>ui/qml/Pages2/PageSettingsAbout.qml</file>
|
||||
<file>images/controls/github.svg</file>
|
||||
<file>images/controls/mail.svg</file>
|
||||
<file>images/controls/telegram.svg</file>
|
||||
<file>ui/qml/Controls2/TextTypes/SmallTextType.qml</file>
|
||||
<file>ui/qml/Filters/ContainersModelFilters.qml</file>
|
||||
<file>ui/qml/Components/SelectLanguageDrawer.qml</file>
|
||||
<file>ui/qml/Controls2/BusyIndicatorType.qml</file>
|
||||
<file>ui/qml/Pages2/PageProtocolOpenVpnSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageProtocolShadowSocksSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageProtocolCloakSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageProtocolXraySettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageProtocolRaw.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsLogging.qml</file>
|
||||
<file>ui/qml/Pages2/PageServiceSftpSettings.qml</file>
|
||||
<file>images/controls/copy.svg</file>
|
||||
<file>ui/qml/Pages2/PageServiceTorWebsiteSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardQrReader.qml</file>
|
||||
<file>images/controls/eye.svg</file>
|
||||
<file>images/controls/eye-off.svg</file>
|
||||
<file>ui/qml/Pages2/PageSettingsSplitTunneling.qml</file>
|
||||
<file>ui/qml/Controls2/ContextMenuType.qml</file>
|
||||
<file>ui/qml/Controls2/TextAreaType.qml</file>
|
||||
<file>images/controls/trash.svg</file>
|
||||
<file>images/controls/more-vertical.svg</file>
|
||||
<file>ui/qml/Controls2/ListViewWithLabelsType.qml</file>
|
||||
<file>ui/qml/Pages2/PageServiceDnsSettings.qml</file>
|
||||
<file>ui/qml/Controls2/TopCloseButtonType.qml</file>
|
||||
<file>images/controls/x-circle.svg</file>
|
||||
<file>ui/qml/Pages2/PageProtocolAwgSettings.qml</file>
|
||||
<file>server_scripts/awg/template.conf</file>
|
||||
<file>server_scripts/awg/start.sh</file>
|
||||
<file>server_scripts/awg/configure_container.sh</file>
|
||||
<file>server_scripts/awg/run_container.sh</file>
|
||||
<file>server_scripts/awg/Dockerfile</file>
|
||||
<file>ui/qml/Pages2/PageShareFullAccess.qml</file>
|
||||
<file>images/controls/close.svg</file>
|
||||
<file>images/controls/search.svg</file>
|
||||
<file>server_scripts/xray/configure_container.sh</file>
|
||||
<file>server_scripts/xray/Dockerfile</file>
|
||||
<file>server_scripts/xray/run_container.sh</file>
|
||||
<file>server_scripts/xray/start.sh</file>
|
||||
<file>server_scripts/xray/template.json</file>
|
||||
<file>ui/qml/Pages2/PageProtocolWireGuardSettings.qml</file>
|
||||
<file>ui/qml/Components/ConnectButton.qml</file>
|
||||
<file>ui/qml/Components/ConnectionTypeSelectionDrawer.qml</file>
|
||||
<file>ui/qml/Components/HomeContainersListView.qml</file>
|
||||
<file>ui/qml/Components/HomeSplitTunnelingDrawer.qml</file>
|
||||
<file>images/controls/split-tunneling.svg</file>
|
||||
<file>ui/qml/Controls2/DrawerType2.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsAppSplitTunneling.qml</file>
|
||||
<file>ui/qml/Components/InstalledAppsDrawer.qml</file>
|
||||
<file>images/controls/alert-circle.svg</file>
|
||||
<file>images/controls/file-check-2.svg</file>
|
||||
<file>ui/qml/Components/QuestionDrawer.qml</file>
|
||||
<file>ui/qml/Components/SelectLanguageDrawer.qml</file>
|
||||
<file>ui/qml/Components/ServersListView.qml</file>
|
||||
<file>ui/qml/Components/SettingsContainersListView.qml</file>
|
||||
<file>ui/qml/Components/ShareConnectionDrawer.qml</file>
|
||||
<file>ui/qml/Components/TransportProtoSelector.qml</file>
|
||||
<file>ui/qml/Config/GlobalConfig.qml</file>
|
||||
<file>ui/qml/Config/qmldir</file>
|
||||
<file>ui/qml/Controls2/BackButtonType.qml</file>
|
||||
<file>ui/qml/Controls2/BasicButtonType.qml</file>
|
||||
<file>ui/qml/Controls2/BusyIndicatorType.qml</file>
|
||||
<file>ui/qml/Controls2/CardType.qml</file>
|
||||
<file>ui/qml/Controls2/CardWithIconsType.qml</file>
|
||||
<file>ui/qml/Controls2/CheckBoxType.qml</file>
|
||||
<file>ui/qml/Controls2/ContextMenuType.qml</file>
|
||||
<file>ui/qml/Controls2/DividerType.qml</file>
|
||||
<file>ui/qml/Controls2/DrawerType2.qml</file>
|
||||
<file>ui/qml/Controls2/DropDownType.qml</file>
|
||||
<file>ui/qml/Controls2/FlickableType.qml</file>
|
||||
<file>ui/qml/Controls2/Header2Type.qml</file>
|
||||
<file>ui/qml/Controls2/HeaderType.qml</file>
|
||||
<file>ui/qml/Controls2/HorizontalRadioButton.qml</file>
|
||||
<file>ui/qml/Controls2/ImageButtonType.qml</file>
|
||||
<file>ui/qml/Controls2/LabelWithButtonType.qml</file>
|
||||
<file>ui/qml/Controls2/LabelWithImageType.qml</file>
|
||||
<file>ui/qml/Controls2/ListViewWithLabelsType.qml</file>
|
||||
<file>ui/qml/Controls2/ListViewWithRadioButtonType.qml</file>
|
||||
<file>ui/qml/Controls2/PageType.qml</file>
|
||||
<file>ui/qml/Controls2/PopupType.qml</file>
|
||||
<file>ui/qml/Controls2/ProgressBarType.qml</file>
|
||||
<file>ui/qml/Controls2/ScrollBarType.qml</file>
|
||||
<file>ui/qml/Controls2/StackViewType.qml</file>
|
||||
<file>ui/qml/Controls2/SwitcherType.qml</file>
|
||||
<file>ui/qml/Controls2/TabButtonType.qml</file>
|
||||
<file>ui/qml/Controls2/TabImageButtonType.qml</file>
|
||||
<file>ui/qml/Controls2/TextAreaType.qml</file>
|
||||
<file>ui/qml/Controls2/TextAreaWithFooterType.qml</file>
|
||||
<file>ui/qml/Controls2/TextFieldWithHeaderType.qml</file>
|
||||
<file>ui/qml/Controls2/TextTypes/ButtonTextType.qml</file>
|
||||
<file>ui/qml/Controls2/TextTypes/CaptionTextType.qml</file>
|
||||
<file>ui/qml/Controls2/TextTypes/Header1TextType.qml</file>
|
||||
<file>ui/qml/Controls2/TextTypes/Header2TextType.qml</file>
|
||||
<file>ui/qml/Controls2/TextTypes/LabelTextType.qml</file>
|
||||
<file>ui/qml/Controls2/TextTypes/ListItemTitleType.qml</file>
|
||||
<file>ui/qml/Controls2/TextTypes/ParagraphTextType.qml</file>
|
||||
<file>ui/qml/Controls2/TextTypes/SmallTextType.qml</file>
|
||||
<file>ui/qml/Controls2/TopCloseButtonType.qml</file>
|
||||
<file>ui/qml/Controls2/VerticalRadioButton.qml</file>
|
||||
<file>ui/qml/Controls2/WarningType.qml</file>
|
||||
<file>fonts/pt-root-ui_vf.ttf</file>
|
||||
<file>ui/qml/Modules/Style/qmldir</file>
|
||||
<file>ui/qml/Filters/ContainersModelFilters.qml</file>
|
||||
<file>ui/qml/main2.qml</file>
|
||||
<file>ui/qml/Modules/Style/AmneziaStyle.qml</file>
|
||||
<file>ui/qml/Modules/Style/qmldir</file>
|
||||
<file>ui/qml/Pages2/PageDeinstalling.qml</file>
|
||||
<file>ui/qml/Pages2/PageDevMenu.qml</file>
|
||||
<file>ui/qml/Pages2/PageHome.qml</file>
|
||||
<file>ui/qml/Pages2/PageProtocolAwgSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageProtocolCloakSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageProtocolOpenVpnSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageProtocolRaw.qml</file>
|
||||
<file>ui/qml/Pages2/PageProtocolShadowSocksSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageProtocolWireGuardSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageProtocolXraySettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageServiceDnsSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageServiceSftpSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageServiceSocksProxySettings.qml</file>
|
||||
<file>server_scripts/socks5_proxy/run_container.sh</file>
|
||||
<file>server_scripts/socks5_proxy/Dockerfile</file>
|
||||
<file>server_scripts/socks5_proxy/configure_container.sh</file>
|
||||
<file>server_scripts/socks5_proxy/start.sh</file>
|
||||
<file>ui/qml/Pages2/PageServiceTorWebsiteSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsAbout.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsApiLanguageList.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsApiServerInfo.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsApplication.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsAppSplitTunneling.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsBackup.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsConnection.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsDns.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsLogging.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsServerData.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsServerInfo.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsServerProtocol.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsServerProtocols.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsServerServices.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsServersList.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsSplitTunneling.qml</file>
|
||||
<file>ui/qml/Pages2/PageProtocolAwgClientSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageProtocolWireGuardClientSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardApiServicesList.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardApiServiceInfo.qml</file>
|
||||
<file>ui/qml/Controls2/CardWithIconsType.qml</file>
|
||||
<file>images/controls/tag.svg</file>
|
||||
<file>images/controls/history.svg</file>
|
||||
<file>images/controls/gauge.svg</file>
|
||||
<file>images/controls/map-pin.svg</file>
|
||||
<file>ui/qml/Controls2/LabelWithImageType.qml</file>
|
||||
<file>images/controls/info.svg</file>
|
||||
<file>ui/qml/Controls2/TextAreaWithFooterType.qml</file>
|
||||
<file>images/controls/scan-line.svg</file>
|
||||
<file>images/controls/folder-search-2.svg</file>
|
||||
<file>ui/qml/Pages2/PageSettingsApiServerInfo.qml</file>
|
||||
<file>images/controls/bug.svg</file>
|
||||
<file>ui/qml/Pages2/PageDevMenu.qml</file>
|
||||
<file>images/controls/refresh-cw.svg</file>
|
||||
<file>ui/qml/Pages2/PageSettingsApiLanguageList.qml</file>
|
||||
<file>images/controls/archive-restore.svg</file>
|
||||
<file>images/controls/help-circle.svg</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardApiServicesList.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardConfigSource.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardCredentials.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardEasy.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardInstalling.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardProtocols.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardProtocolSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardQrReader.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardStart.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardTextKey.qml</file>
|
||||
<file>ui/qml/Pages2/PageSetupWizardViewConfig.qml</file>
|
||||
<file>ui/qml/Pages2/PageShare.qml</file>
|
||||
<file>ui/qml/Pages2/PageShareFullAccess.qml</file>
|
||||
<file>ui/qml/Pages2/PageStart.qml</file>
|
||||
</qresource>
|
||||
<qresource prefix="/countriesFlags">
|
||||
<file>images/flagKit/ZW.svg</file>
|
||||
|
||||
@@ -89,60 +89,60 @@
|
||||
<name>ConnectionController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.h" line="80"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
|
||||
<source>Connect</source>
|
||||
<translation>اتصل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
|
||||
<source>VPN Protocols is not installed.
|
||||
Please install VPN container at first</source>
|
||||
<translation>لم يتم تثبيت بروتوكولات VPN, من فضلك قم بتنزيل حاوية VPN اولاً</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
|
||||
<source>Connecting...</source>
|
||||
<translation>اتصال...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
|
||||
<source>Connected</source>
|
||||
<translation>تم الاتصال</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
|
||||
<source>Reconnecting...</source>
|
||||
<translation>إعادة الاتصال...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
|
||||
<source>Disconnecting...</source>
|
||||
<translation>إنهاء الاتصال...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
|
||||
<source>Preparing...</source>
|
||||
<translation>جاري التحضير...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
|
||||
<source>Settings updated successfully, reconnnection...</source>
|
||||
<translation>تم تحديث الاعدادات بنجاح, جاري إعادة الاتصال...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>تم تحديث الاعدادات بنجاح</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="212"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="209"/>
|
||||
<source>The selected protocol is not supported on the current platform</source>
|
||||
<translation>البروتوكول المحدد غير مدعوم علي المنصة الحالية</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
|
||||
<source>unable to create configuration</source>
|
||||
<translation>غير قادر علي إنشاء تكوين</translation>
|
||||
</message>
|
||||
@@ -253,20 +253,23 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>ImportController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="87"/>
|
||||
<source>Unable to open file</source>
|
||||
<translation type="vanished">غير قادر علي فتح الملف</translation>
|
||||
<translation>غير قادر علي فتح الملف</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="187"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="192"/>
|
||||
<source>Invalid configuration file</source>
|
||||
<translation type="vanished">ملف تكوين غير صحيح</translation>
|
||||
<translation>ملف تكوين غير صحيح</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="623"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="617"/>
|
||||
<source>Scanned %1 of %2.</source>
|
||||
<translation>تم فحص%1 من %2.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="658"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="652"/>
|
||||
<source>In the imported configuration, potentially dangerous lines were found:</source>
|
||||
<translation>في التكوين المستورد، تم العثور على سطور يحتمل أن تكون خطرة:</translation>
|
||||
</message>
|
||||
@@ -274,24 +277,24 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>InstallController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="157"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="181"/>
|
||||
<source>%1 installed successfully. </source>
|
||||
<translation>%1 تم التثبيت بنجاح. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="159"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="183"/>
|
||||
<source>%1 is already installed on the server. </source>
|
||||
<translation>%1 بالفعل مٌثبت علي الخادم. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="179"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="203"/>
|
||||
<source>
|
||||
Added containers that were already installed on the server</source>
|
||||
<translation>
|
||||
تمت إضافة الحاويات التي كانت مٌثبتة بالفعل علي الخادم</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="259"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="283"/>
|
||||
<source>
|
||||
Already installed containers were found on the server. All installed containers have been added to the application</source>
|
||||
<translation>
|
||||
@@ -299,62 +302,62 @@ Already installed containers were found on the server. All installed containers
|
||||
تمت إضافة جميع الحاويات المٌثبتة إلي التطبيق</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="517"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="541"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>تم تحديث الاعدادات بنجاح</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="534"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="558"/>
|
||||
<source>Server '%1' was rebooted</source>
|
||||
<translation>تمت إعادة تشغيل الخادم%1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="546"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="570"/>
|
||||
<source>Server '%1' was removed</source>
|
||||
<translation>تمت إزالة الخادم '%1'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="557"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="581"/>
|
||||
<source>All containers from server '%1' have been removed</source>
|
||||
<translation>قد تم حذفها '%1' جميع الحاويات من الخادم</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="575"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="599"/>
|
||||
<source>%1 has been removed from the server '%2'</source>
|
||||
<translation>%1 تم حدف '%2' اسم الخادم</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="584"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="608"/>
|
||||
<source>Api config removed</source>
|
||||
<translation>تم حذف تكوين Api</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="606"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="630"/>
|
||||
<source>%1 cached profile cleared</source>
|
||||
<translation>تم مسح ملف تعريف %1 المخزن مؤقتًا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="745"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="769"/>
|
||||
<source>Please login as the user</source>
|
||||
<translation>من فضلك قم بتسجيل الدخول كمستخدم</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="773"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="797"/>
|
||||
<source>Server added successfully</source>
|
||||
<translation>تمت إضافة الخادم بنجاح</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="821"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="845"/>
|
||||
<source>%1 installed successfully.</source>
|
||||
<translation>تم تحميل %1 بنجاح</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="855"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="877"/>
|
||||
<source>API config reloaded</source>
|
||||
<translation>تمت إعادة تحميل تكوين API</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="859"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="881"/>
|
||||
<source>Successfully changed the country of connection to %1</source>
|
||||
<translation>تم تغيير بلد الاتصال بنجاح إلى %1</translation>
|
||||
</message>
|
||||
@@ -398,28 +401,28 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>NotificationHandler</name>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="63"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="70"/>
|
||||
<source>AmneziaVPN</source>
|
||||
<translation>AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="65"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<source>VPN Connected</source>
|
||||
<translation>تم الاتصال</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="72"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<source>VPN Disconnected</source>
|
||||
<translation>تم إنهاء الاتصال</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="94"/>
|
||||
<source>AmneziaVPN notification</source>
|
||||
<translation>إشعار من AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="96"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<source>Unsecured network detected: </source>
|
||||
<translation>تم العثور علي شبكة غير مؤمنة: </translation>
|
||||
</message>
|
||||
@@ -2315,107 +2318,97 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>PageSetupWizardConfigSource</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
|
||||
<source>Connection</source>
|
||||
<translation>الاتصال</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished">إعدادات</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
|
||||
<source>Enable logs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
|
||||
<source>Support tag</source>
|
||||
<translation type="unfinished">علامة الدعم</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<source>Copied</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
|
||||
<source>Insert the key, add a configuration file or scan the QR-code</source>
|
||||
<translation>أدخل المفتاح، أضف ملف تكوين أو امسح رمز الاستجابة السريعة</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
|
||||
<source>Insert key</source>
|
||||
<translation>أدخل مفتاح</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<source>Insert</source>
|
||||
<translation>أدخل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
|
||||
<source>Continue</source>
|
||||
<translation>واصل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/>
|
||||
<source>Other connection options</source>
|
||||
<translation>اختيارات اتصال اخري</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/>
|
||||
<source>VPN by Amnezia</source>
|
||||
<translation>VPN بواسطة Amnezia</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/>
|
||||
<source>Connect to classic paid and free VPN services from Amnezia</source>
|
||||
<translation>اتصل بخدمات VPN الكلاسيكية المدفوعة والمجانية من Amnezia</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/>
|
||||
<source>Self-hosted VPN</source>
|
||||
<translation>VPN ذاتية الاستضافة</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/>
|
||||
<source>Configure Amnezia VPN on your own server</source>
|
||||
<translation>قم بتكوين Amnezia VPN على الخادم الخاص بك</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/>
|
||||
<source>Restore from backup</source>
|
||||
<translation>استرجاع من ملف يحتوي علي نسخة احتياطية</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/>
|
||||
<source>Open backup file</source>
|
||||
<translation>افتح ملف نسخ احتياطي</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
|
||||
<source>Backup files (*.backup)</source>
|
||||
<translation>ملفات نٌسخ احتياطية (*.backup)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/>
|
||||
<source>File with connection settings</source>
|
||||
<translation>ملف إعدادات اتصال</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/>
|
||||
<source>Open config file</source>
|
||||
<translation>افتح ملف تكوين</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
|
||||
<source>QR code</source>
|
||||
<translation>رمز QR</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/>
|
||||
<source>I have nothing</source>
|
||||
<translation>ليس لدي اي شئ</translation>
|
||||
</message>
|
||||
@@ -2433,12 +2426,12 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>عنوان خادم IP [:منفذ]</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
|
||||
<source>Continue</source>
|
||||
<translation>واصل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
|
||||
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>ستظل جميع البيانات التي تدخلها سرية للغاية ولن تتم مشاركتها أو الكشف عنها ل Amnezia أو أي طرف ثالث</translation>
|
||||
</message>
|
||||
@@ -2448,42 +2441,42 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
|
||||
<source>SSH Username</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
|
||||
<source>Password or SSH private key</source>
|
||||
<translation>كلمة مرور او مفتاح SSH خاص</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
|
||||
<source>How to run your VPN server</source>
|
||||
<translation>كيف تقوم بتشغيل خادم ال VPN الخاص بك</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
|
||||
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
|
||||
<translation>اين تحصل علي بيانات الاتصال, تعليمات خطوة ب خطوة لشراء VPS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<source>Ip address cannot be empty</source>
|
||||
<translation>لا يمكن لعنوان IP ان يكون فارغ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
|
||||
<source>Enter the address in the format 255.255.255.255:88</source>
|
||||
<translation>ادخل العنوان في شكل 255.255.255.255:88</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
|
||||
<source>Login cannot be empty</source>
|
||||
<translation>تسجيل دخول لا يمكن ان يكون فارغ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
|
||||
<source>Password/private key cannot be empty</source>
|
||||
<translation>كلمة مرور/مفتاح خاص لأ يمكن ان يكونو فارغين</translation>
|
||||
</message>
|
||||
@@ -2778,67 +2771,62 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>ابحث</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/>
|
||||
<source>Creation date: %1</source>
|
||||
<translation>تاريخ الإنشاء: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/>
|
||||
<source>Latest handshake: %1</source>
|
||||
<translation>اخر تصافح: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/>
|
||||
<source>Data received: %1</source>
|
||||
<translation>البيانات المستلمة: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/>
|
||||
<source>Data sent: %1</source>
|
||||
<translation>البيانات المٌرسلة: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
|
||||
<source>Allowed IPs: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
|
||||
<source>Rename</source>
|
||||
<translation>إعادة التسمية</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
|
||||
<source>Client name</source>
|
||||
<translation>اسم العميل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
|
||||
<source>Save</source>
|
||||
<translation>احفظ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
|
||||
<source>Revoke</source>
|
||||
<translation>سحب وإبطال</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
|
||||
<source>Revoke the config for a user - %1?</source>
|
||||
<translation>سحب وإبطال للمستخدم - %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<source>The user will no longer be able to connect to your server.</source>
|
||||
<translation>المستخدم لن يكون قادر علي الاتصال بعد الان.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
|
||||
<source>Continue</source>
|
||||
<translation>واصل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
|
||||
<source>Cancel</source>
|
||||
<translation>إلغاء</translation>
|
||||
</message>
|
||||
@@ -2951,17 +2939,17 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>PageStart</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/>
|
||||
<source>Logging was disabled after 14 days, log files were deleted</source>
|
||||
<translation>تم تعطيل التسجيل بعد 14 يومًا، وتم حذف ملفات السجل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
|
||||
<source>Settings restored from backup file</source>
|
||||
<translation>تم تحميل الإعدادات من ملف نسخة احتياطية</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/>
|
||||
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -3300,22 +3288,22 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>انتهت مدة الاتصال بالخادم</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="56"/>
|
||||
<location filename="../core/errorstrings.cpp" line="55"/>
|
||||
<source>VPN connection error</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<location filename="../core/errorstrings.cpp" line="58"/>
|
||||
<source>Error when retrieving configuration from API</source>
|
||||
<translation>خطأ عند استرداد التكوين من API</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="60"/>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<source>This config has already been added to the application</source>
|
||||
<translation>هذا التكوين بالفعل تمت إضافتة للبرنامج</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="80"/>
|
||||
<location filename="../core/errorstrings.cpp" line="78"/>
|
||||
<source>ErrorCode: %1. </source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
@@ -3390,67 +3378,57 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>التكوين لا يحتوي علي اي حاويات و اعتماد للأتصال بالخادم</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="53"/>
|
||||
<source>Unable to open config file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<location filename="../core/errorstrings.cpp" line="60"/>
|
||||
<source>In the response from the server, an empty config was received</source>
|
||||
<translation>في الاستجابة من الخادم، تم تلقي تكوين فارغ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<source>SSL error occurred</source>
|
||||
<translation>حدث خطأ SSL</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<source>Server response timeout on api request</source>
|
||||
<translation>انتهت مهلة استجابة الخادم عند طلب واجهة برمجة التطبيقات</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="64"/>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<source>Missing AGW public key</source>
|
||||
<translation>مفتاح AGW عام مفقود</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="65"/>
|
||||
<source>Failed to decrypt response payload</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="68"/>
|
||||
<location filename="../core/errorstrings.cpp" line="66"/>
|
||||
<source>QFile error: The file could not be opened</source>
|
||||
<translation>خطأ QFile: لا يمكن فتح الملف</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<location filename="../core/errorstrings.cpp" line="67"/>
|
||||
<source>QFile error: An error occurred when reading from the file</source>
|
||||
<translation>خطأ QFile: ظهر خطأ اثناء القراءه من الملف</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<location filename="../core/errorstrings.cpp" line="68"/>
|
||||
<source>QFile error: The file could not be accessed</source>
|
||||
<translation>خطأ QFile: لا يمكن الوصول للملف</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<source>QFile error: An unspecified error occurred</source>
|
||||
<translation>خطأ QFile: ظهر خطأ غير محدد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="72"/>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<source>QFile error: A fatal error occurred</source>
|
||||
<translation>خطأ QFile: حدث خطأ فادح</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="73"/>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<source>QFile error: The operation was aborted</source>
|
||||
<translation>خطأ QFile: تم إحباط العملية</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="77"/>
|
||||
<location filename="../core/errorstrings.cpp" line="75"/>
|
||||
<source>Internal error</source>
|
||||
<translation>خطأ داخلي</translation>
|
||||
</message>
|
||||
@@ -4048,7 +4026,7 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||
<context>
|
||||
<name>VpnConnection</name>
|
||||
<message>
|
||||
<location filename="../vpnconnection.cpp" line="409"/>
|
||||
<location filename="../vpnconnection.cpp" line="408"/>
|
||||
<source>Mbps</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
@@ -4122,12 +4100,12 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||
<context>
|
||||
<name>main2</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="163"/>
|
||||
<location filename="../ui/qml/main2.qml" line="162"/>
|
||||
<source>Private key passphrase</source>
|
||||
<translation>عبارة المرور الخاصة بالمفتاح</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="186"/>
|
||||
<location filename="../ui/qml/main2.qml" line="185"/>
|
||||
<source>Save</source>
|
||||
<translation>احفظ</translation>
|
||||
</message>
|
||||
|
||||
@@ -88,63 +88,63 @@
|
||||
<context>
|
||||
<name>ConnectionController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
|
||||
<source>VPN Protocols is not installed.
|
||||
Please install VPN container at first</source>
|
||||
<translation>پروتکل ویپیان نصب نشده است
|
||||
لطفا کانتینر ویپیان را نصب کنید</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
|
||||
<source>Connecting...</source>
|
||||
<translation>در حال ارتباط...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
|
||||
<source>Connected</source>
|
||||
<translation>متصل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
|
||||
<source>Preparing...</source>
|
||||
<translation>در حال آمادهسازی...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
|
||||
<source>Settings updated successfully, reconnnection...</source>
|
||||
<translation>تنظیمات به روز رسانی شد
|
||||
در حال اتصال دوباره...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>تنظیمات با موفقیت بهروزرسانی شدند</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="212"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="209"/>
|
||||
<source>The selected protocol is not supported on the current platform</source>
|
||||
<translation>پروتکل انتخابشده در پلتفرم فعلی پشتیبانی نمیشود.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
|
||||
<source>unable to create configuration</source>
|
||||
<translation>نمیتوان پیکربندی را ایجاد کرد.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
|
||||
<source>Reconnecting...</source>
|
||||
<translation>اتصال دوباره...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.h" line="80"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
|
||||
<source>Connect</source>
|
||||
<translation>اتصال</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
|
||||
<source>Disconnecting...</source>
|
||||
<translation>قطع ارتباط...</translation>
|
||||
</message>
|
||||
@@ -258,20 +258,23 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>ImportController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="87"/>
|
||||
<source>Unable to open file</source>
|
||||
<translation type="vanished">نمیتوان فایل را باز کرد.</translation>
|
||||
<translation>نمیتوان فایل را باز کرد.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="187"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="192"/>
|
||||
<source>Invalid configuration file</source>
|
||||
<translation type="vanished">فایل پیکربندی نامعتبر است.</translation>
|
||||
<translation>فایل پیکربندی نامعتبر است.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="623"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="617"/>
|
||||
<source>Scanned %1 of %2.</source>
|
||||
<translation>ارزیابی %1 از %2.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="658"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="652"/>
|
||||
<source>In the imported configuration, potentially dangerous lines were found:</source>
|
||||
<translation>در پیکربندی وارد شده، خطوطی که ممکن است خطرناک باشند، یافت شدند:</translation>
|
||||
</message>
|
||||
@@ -279,86 +282,86 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>InstallController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="157"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="181"/>
|
||||
<source>%1 installed successfully. </source>
|
||||
<translation>%1 با موفقیت نصب شد. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="159"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="183"/>
|
||||
<source>%1 is already installed on the server. </source>
|
||||
<translation>%1 در حال حاضر بر روی سرور نصب شده است. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="179"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="203"/>
|
||||
<source>
|
||||
Added containers that were already installed on the server</source>
|
||||
<translation>
|
||||
کانتینرهایی که بر روی سرور موجود بودند اضافه شدند</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="259"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="283"/>
|
||||
<source>
|
||||
Already installed containers were found on the server. All installed containers have been added to the application</source>
|
||||
<translation>
|
||||
کانتینرهای نصب شده بر روی سرور شناسایی شدند. تمام کانتینترهای نصب شده به نرم افزار اضافه شدند</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="517"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="541"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>تنظیمات با موفقیت بهروزرسانی شدند</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="534"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="558"/>
|
||||
<source>Server '%1' was rebooted</source>
|
||||
<translation>سرور %1 راه اندازی مجدد شد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="546"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="570"/>
|
||||
<source>Server '%1' was removed</source>
|
||||
<translation>سرور %1 حذف شد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="557"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="581"/>
|
||||
<source>All containers from server '%1' have been removed</source>
|
||||
<translation>تمام کانتینترها از سرور %1 حذف شدند</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="575"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="599"/>
|
||||
<source>%1 has been removed from the server '%2'</source>
|
||||
<translation>%1 از سرور %2 حذف شد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="584"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="608"/>
|
||||
<source>Api config removed</source>
|
||||
<translation>پیکربندی API حذف شد.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="606"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="630"/>
|
||||
<source>%1 cached profile cleared</source>
|
||||
<translation>%1 پروفایل ذخیره شده پاک شد.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="745"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="769"/>
|
||||
<source>Please login as the user</source>
|
||||
<translation>لطفا به عنوان کاربر وارد شوید</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="773"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="797"/>
|
||||
<source>Server added successfully</source>
|
||||
<translation>سرور با موفقیت اضافه شد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="821"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="845"/>
|
||||
<source>%1 installed successfully.</source>
|
||||
<translation>%1 با موفقیت نصب شد.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="855"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="877"/>
|
||||
<source>API config reloaded</source>
|
||||
<translation>پیکربندی API دوباره بارگذاری شد.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="859"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="881"/>
|
||||
<source>Successfully changed the country of connection to %1</source>
|
||||
<translation>کشور اتصال با موفقیت به %1 تغییر یافت.</translation>
|
||||
</message>
|
||||
@@ -402,28 +405,28 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>NotificationHandler</name>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="63"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="70"/>
|
||||
<source>AmneziaVPN</source>
|
||||
<translation>AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="65"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<source>VPN Connected</source>
|
||||
<translation>ویپیان وصل شد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="72"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<source>VPN Disconnected</source>
|
||||
<translation>ویپیان قطع شد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="94"/>
|
||||
<source>AmneziaVPN notification</source>
|
||||
<translation>اخطار AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="96"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<source>Unsecured network detected: </source>
|
||||
<translation>شبکه ناامن شناسایی شد: </translation>
|
||||
</message>
|
||||
@@ -2430,7 +2433,7 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">چی داری؟</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/>
|
||||
<source>File with connection settings</source>
|
||||
<translation>فایل شامل تنظیمات اتصال</translation>
|
||||
</message>
|
||||
@@ -2439,102 +2442,92 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">فایل شامل تنظیمات اتصال یا بکآپ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
|
||||
<source>Connection</source>
|
||||
<translation>ارتباط</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished">تنظیمات</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
|
||||
<source>Enable logs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
|
||||
<source>Support tag</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<source>Copied</source>
|
||||
<translation type="unfinished">کپی شد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
|
||||
<source>Insert the key, add a configuration file or scan the QR-code</source>
|
||||
<translation>کلید را وارد کنید، فایل پیکربندی را اضافه کنید یا کد QR را اسکن کنید</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
|
||||
<source>Insert key</source>
|
||||
<translation>کلید را وارد کنید</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<source>Insert</source>
|
||||
<translation>وارد کردن</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
|
||||
<source>Continue</source>
|
||||
<translation>ادامه دهید</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/>
|
||||
<source>Other connection options</source>
|
||||
<translation>گزینههای اتصال دیگر</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/>
|
||||
<source>VPN by Amnezia</source>
|
||||
<translation>VPN توسط Amnezia</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/>
|
||||
<source>Connect to classic paid and free VPN services from Amnezia</source>
|
||||
<translation>اتصال به سرویسهای VPN کلاسیک پولی و رایگان از Amnezia</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/>
|
||||
<source>Self-hosted VPN</source>
|
||||
<translation>Self-hosted VPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/>
|
||||
<source>Configure Amnezia VPN on your own server</source>
|
||||
<translation>پیکربندی VPN Amnezia بر روی سرور خودتان</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/>
|
||||
<source>Restore from backup</source>
|
||||
<translation>بازیابی از پشتیبان</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/>
|
||||
<source>Open backup file</source>
|
||||
<translation>باز کردن فایل پشتیبان</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
|
||||
<source>Backup files (*.backup)</source>
|
||||
<translation>Backup files (*.backup)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/>
|
||||
<source>Open config file</source>
|
||||
<translation>باز کردن فایل تنظیمات</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
|
||||
<source>QR code</source>
|
||||
<translation>QR-Code</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/>
|
||||
<source>I have nothing</source>
|
||||
<translation>من هیچی ندارم</translation>
|
||||
</message>
|
||||
@@ -2551,12 +2544,12 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation>آدرس آیپی سرور (:پورت)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
|
||||
<source>Continue</source>
|
||||
<translation>ادامه</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
|
||||
<source>Enter the address in the format 255.255.255.255:88</source>
|
||||
<translation>آدرس را با فرمت 255.255.255.255:88 وارد کنید</translation>
|
||||
</message>
|
||||
@@ -2571,42 +2564,42 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
|
||||
<source>SSH Username</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
|
||||
<source>Password or SSH private key</source>
|
||||
<translation>رمز عبور یا کلید خصوصی SSH</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
|
||||
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>تمام دادههایی که شما وارد میکنید به شدت محرمانه است و با Amnezia یا هر شخص ثالث دیگری به اشتراک گذاشته نمیشود</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
|
||||
<source>How to run your VPN server</source>
|
||||
<translation>چگونه سرور VPN خود را اجرا کنید</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
|
||||
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
|
||||
<translation>دادههای اتصال را از کجا دریافت کنید و دستورالعملهای مرحله به مرحله برای خرید یک VPS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<source>Ip address cannot be empty</source>
|
||||
<translation>آدرس آیپی نمیتواند خالی باشد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
|
||||
<source>Login cannot be empty</source>
|
||||
<translation>نامکاربری نمیتواند خالی باشد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
|
||||
<source>Password/private key cannot be empty</source>
|
||||
<translation>پسورد یا کلید خصوصی نمیتواند خالی باشد</translation>
|
||||
</message>
|
||||
@@ -2946,71 +2939,66 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation>جستجو</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/>
|
||||
<source>Creation date: %1</source>
|
||||
<translation>تاریخ ایجاد: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/>
|
||||
<source>Latest handshake: %1</source>
|
||||
<translation>آخرین ارتباط: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/>
|
||||
<source>Data received: %1</source>
|
||||
<translation>دادههای دریافت شده: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/>
|
||||
<source>Data sent: %1</source>
|
||||
<translation>دادههای ارسال شده: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
|
||||
<source>Allowed IPs: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Creation date: </source>
|
||||
<translation type="vanished">تاریخ ایجاد: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
|
||||
<source>Rename</source>
|
||||
<translation>تغییر نام</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
|
||||
<source>Client name</source>
|
||||
<translation>نام کلاینت</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
|
||||
<source>Save</source>
|
||||
<translation>ذخیره</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
|
||||
<source>Revoke</source>
|
||||
<translation>ابطال</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
|
||||
<source>Revoke the config for a user - %1?</source>
|
||||
<translation>لغو پیکربندی برای یک کاربر - %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<source>The user will no longer be able to connect to your server.</source>
|
||||
<translation>کاربر دیگر نمیتواند به سرور وصل شود.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
|
||||
<source>Continue</source>
|
||||
<translation>ادامه</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
|
||||
<source>Cancel</source>
|
||||
<translation>کنسل</translation>
|
||||
</message>
|
||||
@@ -3097,17 +3085,17 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<context>
|
||||
<name>PageStart</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/>
|
||||
<source>Logging was disabled after 14 days, log files were deleted</source>
|
||||
<translation>ثبت وقایع پس از ۱۴ روز غیرفعال شد و فایلهای ثبت وقایع حذف شدند</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
|
||||
<source>Settings restored from backup file</source>
|
||||
<translation>تنظیمات از فایل پشتیبان بازیابی شد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/>
|
||||
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -3491,22 +3479,22 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation>تنظیمات شامل هیچ کانتینر یا اعتبارنامهای برای اتصال به سرور نیست</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="56"/>
|
||||
<location filename="../core/errorstrings.cpp" line="55"/>
|
||||
<source>VPN connection error</source>
|
||||
<translation>خطای اتصال VPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<location filename="../core/errorstrings.cpp" line="58"/>
|
||||
<source>Error when retrieving configuration from API</source>
|
||||
<translation>خطا هنگام بازیابی پیکربندی از API</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="60"/>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<source>This config has already been added to the application</source>
|
||||
<translation>این پیکربندی قبلاً به برنامه اضافه شده است</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="80"/>
|
||||
<location filename="../core/errorstrings.cpp" line="78"/>
|
||||
<source>ErrorCode: %1. </source>
|
||||
<translation>کد خطا: %1. </translation>
|
||||
</message>
|
||||
@@ -3576,67 +3564,57 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation>VPN pool error: no available addresses</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="53"/>
|
||||
<source>Unable to open config file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<location filename="../core/errorstrings.cpp" line="60"/>
|
||||
<source>In the response from the server, an empty config was received</source>
|
||||
<translation>در پاسخ از سرور، پیکربندی خالی دریافت شد</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<source>SSL error occurred</source>
|
||||
<translation type="unfinished">SSL error occurred</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<source>Server response timeout on api request</source>
|
||||
<translation>Server response timeout on api request</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="64"/>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<source>Missing AGW public key</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="65"/>
|
||||
<source>Failed to decrypt response payload</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="68"/>
|
||||
<location filename="../core/errorstrings.cpp" line="66"/>
|
||||
<source>QFile error: The file could not be opened</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<location filename="../core/errorstrings.cpp" line="67"/>
|
||||
<source>QFile error: An error occurred when reading from the file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<location filename="../core/errorstrings.cpp" line="68"/>
|
||||
<source>QFile error: The file could not be accessed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<source>QFile error: An unspecified error occurred</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="72"/>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<source>QFile error: A fatal error occurred</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="73"/>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<source>QFile error: The operation was aborted</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="77"/>
|
||||
<location filename="../core/errorstrings.cpp" line="75"/>
|
||||
<source>Internal error</source>
|
||||
<translation>Internal error</translation>
|
||||
</message>
|
||||
@@ -4256,7 +4234,7 @@ For more detailed information, you can
|
||||
<context>
|
||||
<name>VpnConnection</name>
|
||||
<message>
|
||||
<location filename="../vpnconnection.cpp" line="409"/>
|
||||
<location filename="../vpnconnection.cpp" line="408"/>
|
||||
<source>Mbps</source>
|
||||
<translation>Mbps</translation>
|
||||
</message>
|
||||
@@ -4338,12 +4316,12 @@ For more detailed information, you can
|
||||
<context>
|
||||
<name>main2</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="163"/>
|
||||
<location filename="../ui/qml/main2.qml" line="162"/>
|
||||
<source>Private key passphrase</source>
|
||||
<translation>عبارت کلید خصوصی</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="186"/>
|
||||
<location filename="../ui/qml/main2.qml" line="185"/>
|
||||
<source>Save</source>
|
||||
<translation>ذخیره</translation>
|
||||
</message>
|
||||
|
||||
@@ -89,61 +89,61 @@
|
||||
<name>ConnectionController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.h" line="80"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
|
||||
<source>Connect</source>
|
||||
<translation>कनेक्ट</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
|
||||
<source>VPN Protocols is not installed.
|
||||
Please install VPN container at first</source>
|
||||
<translation>पीएन प्रोटोकॉल स्थापित नहीं है.
|
||||
कृपया पहले वीपीएन कंटेनर स्थापित करें</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
|
||||
<source>Connected</source>
|
||||
<translation>जुड़ा हुआ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="212"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="209"/>
|
||||
<source>The selected protocol is not supported on the current platform</source>
|
||||
<translation>चयनित प्रोटोकॉल वर्तमान प्लेटफ़ॉर्म पर समर्थित नहीं है</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
|
||||
<source>unable to create configuration</source>
|
||||
<translation>कॉन्फ़िगरेशन बनाने में असमर्थ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
|
||||
<source>Connecting...</source>
|
||||
<translation>कनेक्ट...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
|
||||
<source>Reconnecting...</source>
|
||||
<translation>पुनः कनेक्ट हो रहा है...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
|
||||
<source>Disconnecting...</source>
|
||||
<translation>डिस्कनेक्ट हो रहा है...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
|
||||
<source>Preparing...</source>
|
||||
<translation>तैयार कर रहे हैं...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
|
||||
<source>Settings updated successfully, reconnnection...</source>
|
||||
<translation>सेटिंग्स सफलतापूर्वक अपडेट हो गईं...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>सेटिंग्स सफलतापूर्वक अपडेट हो गईं</translation>
|
||||
</message>
|
||||
@@ -254,20 +254,23 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>ImportController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="87"/>
|
||||
<source>Unable to open file</source>
|
||||
<translation type="vanished">फाइल खोलने में असमर्थ</translation>
|
||||
<translation>फाइल खोलने में असमर्थ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="187"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="192"/>
|
||||
<source>Invalid configuration file</source>
|
||||
<translation type="vanished">अमान्य कॉन्फ़िगरेशन फ़ाइल</translation>
|
||||
<translation>अमान्य कॉन्फ़िगरेशन फ़ाइल</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="623"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="617"/>
|
||||
<source>Scanned %1 of %2.</source>
|
||||
<translation>%2 में से %1 स्कैन किया गया.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="658"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="652"/>
|
||||
<source>In the imported configuration, potentially dangerous lines were found:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -275,86 +278,86 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>InstallController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="157"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="181"/>
|
||||
<source>%1 installed successfully. </source>
|
||||
<translation>%1 सफलतापूर्वक स्थापित हुआ. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="159"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="183"/>
|
||||
<source>%1 is already installed on the server. </source>
|
||||
<translation>%1 पहले से ही सर्वर पर स्थापित है. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="179"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="203"/>
|
||||
<source>
|
||||
Added containers that were already installed on the server</source>
|
||||
<translation>
|
||||
सर्वर पर पहले से स्थापित कंटेनर जोड़े गए</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="259"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="283"/>
|
||||
<source>
|
||||
Already installed containers were found on the server. All installed containers have been added to the application</source>
|
||||
<translation>
|
||||
सर्वर पर पहले से स्थापित कंटेनर पाए गए। सभी स्थापित कंटेनरों को एप्लिकेशन में जोड़ दिया गया है</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="517"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="541"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>सेटिंग्स सफलतापूर्वक अपडेट हो गईं</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="534"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="558"/>
|
||||
<source>Server '%1' was rebooted</source>
|
||||
<translation>सर्वर '%1' रीबूट किया गया था</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="546"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="570"/>
|
||||
<source>Server '%1' was removed</source>
|
||||
<translation>सर्वर '%1' रीबूट किया गया था</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="557"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="581"/>
|
||||
<source>All containers from server '%1' have been removed</source>
|
||||
<translation>सर्वर '%1' से सभी कंटेनर हटा दिए गए हैं</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="575"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="599"/>
|
||||
<source>%1 has been removed from the server '%2'</source>
|
||||
<translation>%1 को सर्वर '%2' से हटा दिया गया है</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="584"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="608"/>
|
||||
<source>Api config removed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="606"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="630"/>
|
||||
<source>%1 cached profile cleared</source>
|
||||
<translation>%1 कैश्ड प्रोफ़ाइल साफ़ की गई</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="745"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="769"/>
|
||||
<source>Please login as the user</source>
|
||||
<translation>कृपया उपयोगकर्ता के रूप में लॉगिन करें</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="773"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="797"/>
|
||||
<source>Server added successfully</source>
|
||||
<translation>सर्वर सफलतापूर्वक जोड़ा गया</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="821"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="845"/>
|
||||
<source>%1 installed successfully.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="855"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="877"/>
|
||||
<source>API config reloaded</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="859"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="881"/>
|
||||
<source>Successfully changed the country of connection to %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -398,28 +401,28 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>NotificationHandler</name>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="63"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="70"/>
|
||||
<source>AmneziaVPN</source>
|
||||
<translation>AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="65"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<source>VPN Connected</source>
|
||||
<translation>कनेक्ट</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="72"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<source>VPN Disconnected</source>
|
||||
<translation>कनेक्ट</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="94"/>
|
||||
<source>AmneziaVPN notification</source>
|
||||
<translation>AmneziaVPN अधिसूचना</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="96"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<source>Unsecured network detected: </source>
|
||||
<translation>असुरक्षित नेटवर्क का पता चला: </translation>
|
||||
</message>
|
||||
@@ -2379,107 +2382,97 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation type="vanished">कनेक्शन सेटिंग्स वाली फ़ाइल</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
|
||||
<source>Connection</source>
|
||||
<translation type="unfinished">कनेक्शन</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished">समायोजन</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
|
||||
<source>Enable logs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
|
||||
<source>Support tag</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<source>Copied</source>
|
||||
<translation type="unfinished">कॉपी किया गया</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
|
||||
<source>Insert the key, add a configuration file or scan the QR-code</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
|
||||
<source>Insert key</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<source>Insert</source>
|
||||
<translation type="unfinished">डालना</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
|
||||
<source>Continue</source>
|
||||
<translation type="unfinished">जारी रखना</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/>
|
||||
<source>Other connection options</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/>
|
||||
<source>VPN by Amnezia</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/>
|
||||
<source>Connect to classic paid and free VPN services from Amnezia</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/>
|
||||
<source>Self-hosted VPN</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/>
|
||||
<source>Configure Amnezia VPN on your own server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/>
|
||||
<source>Restore from backup</source>
|
||||
<translation type="unfinished">बैकअप से बहाल करना</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/>
|
||||
<source>Open backup file</source>
|
||||
<translation type="unfinished">बैकअप फ़ाइल खोलें</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
|
||||
<source>Backup files (*.backup)</source>
|
||||
<translation type="unfinished">बैकअप फ़ाइलें (*.backup)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/>
|
||||
<source>File with connection settings</source>
|
||||
<translation>कनेक्शन सेटिंग्स वाली फ़ाइल</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/>
|
||||
<source>Open config file</source>
|
||||
<translation>कॉन्फ़िग फ़ाइल खोलें</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
|
||||
<source>QR code</source>
|
||||
<translation>क्यू आर संहिता</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/>
|
||||
<source>I have nothing</source>
|
||||
<translation type="unfinished">मेरे पास कुछ नहीं है</translation>
|
||||
</message>
|
||||
@@ -2501,12 +2494,12 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>सर्वर आईपी पता [:पोर्ट]</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
|
||||
<source>Continue</source>
|
||||
<translation>जारी रखना</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
|
||||
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>आपके द्वारा दर्ज किया गया सभी डेटा पूरी तरह से गोपनीय रहेगा और एमनेज़िया या किसी तीसरे पक्ष को साझा या प्रकट नहीं किया जाएगा</translation>
|
||||
</message>
|
||||
@@ -2516,42 +2509,42 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>255.255.255.255:22</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
|
||||
<source>SSH Username</source>
|
||||
<translation>SSH उपयोगकर्ता नाम</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
|
||||
<source>Password or SSH private key</source>
|
||||
<translation>पासवर्ड या SSH निजी कुंजी</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
|
||||
<source>How to run your VPN server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
|
||||
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<source>Ip address cannot be empty</source>
|
||||
<translation>आईपी पता खाली नहीं हो सकता</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
|
||||
<source>Enter the address in the format 255.255.255.255:88</source>
|
||||
<translation>पता 255.255.255.255:88 प्रारूप में दर्ज करें</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
|
||||
<source>Login cannot be empty</source>
|
||||
<translation>लॉगिन खाली नहीं हो सकता</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
|
||||
<source>Password/private key cannot be empty</source>
|
||||
<translation>पासवर्ड/निजी कुंजी खाली नहीं हो सकती</translation>
|
||||
</message>
|
||||
@@ -2864,71 +2857,66 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>खोज</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/>
|
||||
<source>Creation date: %1</source>
|
||||
<translation>निर्माण दिनांक: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/>
|
||||
<source>Latest handshake: %1</source>
|
||||
<translation>नवीनतम हाथ मिलाना: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/>
|
||||
<source>Data received: %1</source>
|
||||
<translation>प्राप्त डेटा: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/>
|
||||
<source>Data sent: %1</source>
|
||||
<translation>डेटा भेजा गया: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
|
||||
<source>Allowed IPs: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Creation date: </source>
|
||||
<translation type="vanished">निर्माण तिथि: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
|
||||
<source>Rename</source>
|
||||
<translation>नाम बदलें</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
|
||||
<source>Client name</source>
|
||||
<translation>ग्राहक नाम</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
|
||||
<source>Save</source>
|
||||
<translation>सहेजें</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
|
||||
<source>Revoke</source>
|
||||
<translation>निरस्त करें</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
|
||||
<source>Revoke the config for a user - %1?</source>
|
||||
<translation>किसी उपयोक्ता के लिए कॉन्फ़िगरेशन निरस्त करें - %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<source>The user will no longer be able to connect to your server.</source>
|
||||
<translation>उपयोगकर्ता अब आपके सर्वर से कनेक्ट नहीं हो पाएगा.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
|
||||
<source>Continue</source>
|
||||
<translation>जारी रखना</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
|
||||
<source>Cancel</source>
|
||||
<translation>रद्द करना</translation>
|
||||
</message>
|
||||
@@ -3046,17 +3034,17 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>PageStart</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/>
|
||||
<source>Logging was disabled after 14 days, log files were deleted</source>
|
||||
<translation>14 दिनों के बाद लॉगिंग अक्षम कर दी गई, लॉग फ़ाइलें हटा दी गईं</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
|
||||
<source>Settings restored from backup file</source>
|
||||
<translation type="unfinished">बैकअप फ़ाइल से सेटिंग्स पुनर्स्थापित की गईं</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/>
|
||||
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -3405,52 +3393,42 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>सर्वर से कनेक्ट होने का समय समाप्त</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="53"/>
|
||||
<source>Unable to open config file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="56"/>
|
||||
<location filename="../core/errorstrings.cpp" line="55"/>
|
||||
<source>VPN connection error</source>
|
||||
<translation>VPN कनेक्शन त्रुटि</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<location filename="../core/errorstrings.cpp" line="58"/>
|
||||
<source>Error when retrieving configuration from API</source>
|
||||
<translation>एपीआई से कॉन्फ़िगरेशन पुनर्प्राप्त करते समय त्रुटि</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="60"/>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<source>This config has already been added to the application</source>
|
||||
<translation>यह कॉन्फ़िगरेशन पहले ही एप्लिकेशन में जोड़ा जा चुका है</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<location filename="../core/errorstrings.cpp" line="60"/>
|
||||
<source>In the response from the server, an empty config was received</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<source>SSL error occurred</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<source>Server response timeout on api request</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="64"/>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<source>Missing AGW public key</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="65"/>
|
||||
<source>Failed to decrypt response payload</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="80"/>
|
||||
<location filename="../core/errorstrings.cpp" line="78"/>
|
||||
<source>ErrorCode: %1. </source>
|
||||
<translation>ErrorCode: %1. </translation>
|
||||
</message>
|
||||
@@ -3515,37 +3493,37 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>कॉन्फ़िगरेशन में सर्वर से कनेक्ट करने के लिए कोई कंटेनर और क्रेडेंशियल नहीं है</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="68"/>
|
||||
<location filename="../core/errorstrings.cpp" line="66"/>
|
||||
<source>QFile error: The file could not be opened</source>
|
||||
<translation>Qफ़ाइल त्रुटि: फ़ाइल खोली नहीं जा सकी</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<location filename="../core/errorstrings.cpp" line="67"/>
|
||||
<source>QFile error: An error occurred when reading from the file</source>
|
||||
<translation>Qफ़ाइल त्रुटि: फ़ाइल से पढ़ते समय एक त्रुटि उत्पन्न हुई</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<location filename="../core/errorstrings.cpp" line="68"/>
|
||||
<source>QFile error: The file could not be accessed</source>
|
||||
<translation>Qफ़ाइल त्रुटि: फ़ाइल तक नहीं पहुंचा जा सका</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<source>QFile error: An unspecified error occurred</source>
|
||||
<translation>Qफ़ाइल त्रुटि: एक अनिर्दिष्ट त्रुटि उत्पन्न हुई</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="72"/>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<source>QFile error: A fatal error occurred</source>
|
||||
<translation>Qफ़ाइल त्रुटि: एक घातक त्रुटि उत्पन्न हुई</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="73"/>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<source>QFile error: The operation was aborted</source>
|
||||
<translation>Qफ़ाइल त्रुटि: ऑपरेशन निरस्त कर दिया गया था</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="77"/>
|
||||
<location filename="../core/errorstrings.cpp" line="75"/>
|
||||
<source>Internal error</source>
|
||||
<translation>आंतरिक त्रुटि</translation>
|
||||
</message>
|
||||
@@ -4144,7 +4122,7 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||
<context>
|
||||
<name>VpnConnection</name>
|
||||
<message>
|
||||
<location filename="../vpnconnection.cpp" line="409"/>
|
||||
<location filename="../vpnconnection.cpp" line="408"/>
|
||||
<source>Mbps</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
@@ -4230,12 +4208,12 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||
<context>
|
||||
<name>main2</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="163"/>
|
||||
<location filename="../ui/qml/main2.qml" line="162"/>
|
||||
<source>Private key passphrase</source>
|
||||
<translation>निजी कुंजी पासफ़्रेज़</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="186"/>
|
||||
<location filename="../ui/qml/main2.qml" line="185"/>
|
||||
<source>Save</source>
|
||||
<translation>सहेजें</translation>
|
||||
</message>
|
||||
|
||||
@@ -88,62 +88,62 @@
|
||||
<context>
|
||||
<name>ConnectionController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
|
||||
<source>VPN Protocols is not installed.
|
||||
Please install VPN container at first</source>
|
||||
<translation>VPN ပရိုတိုကောများကို မထည့်သွင်းရသေးပါ။
|
||||
ကျေးဇူးပြု၍ VPN ကွန်တိန်နာကို အရင်ထည့်သွင်းပါ။</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
|
||||
<source>Connecting...</source>
|
||||
<translation>ချိတ်ဆက်နေပါပြီ...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
|
||||
<source>Connected</source>
|
||||
<translation>ချိတ်ဆက်ပြီးသွားပါပြီ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
|
||||
<source>Preparing...</source>
|
||||
<translation>ပြင်ဆင်နေသည်...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
|
||||
<source>Settings updated successfully, reconnnection...</source>
|
||||
<translation>ဆက်တင်များကို အောင်မြင်စွာ အပ်ဒိတ်လုပ်ပြီးပါပြီ၊ ပြန်လည်ချိတ်ဆက်နေပါသည်...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>ဆက်တင်များကို အောင်မြင်စွာ အပ်ဒိတ်လုပ်ပြီးပါပြီ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="212"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="209"/>
|
||||
<source>The selected protocol is not supported on the current platform</source>
|
||||
<translation>ရွေးချယ်ထားသော ပရိုတိုကောကို လက်ရှိပလက်ဖောင်းပေါ်တွင် အထောက်အပံ့မပေးထားပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
|
||||
<source>unable to create configuration</source>
|
||||
<translation>configuration ဖန်တီး၍မရပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
|
||||
<source>Reconnecting...</source>
|
||||
<translation>ပြန်လည်ချိတ်ဆက်နေပါသည်...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.h" line="80"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
|
||||
<source>Connect</source>
|
||||
<translation>ချိတ်ဆက်မည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
|
||||
<source>Disconnecting...</source>
|
||||
<translation>အဆက်အသွယ်ဖြတ်နေပါသည်...</translation>
|
||||
</message>
|
||||
@@ -254,20 +254,23 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>ImportController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="87"/>
|
||||
<source>Unable to open file</source>
|
||||
<translation type="vanished">ဖိုင်ကိုဖွင့်၍မရပါ</translation>
|
||||
<translation>ဖိုင်ကိုဖွင့်၍မရပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="187"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="192"/>
|
||||
<source>Invalid configuration file</source>
|
||||
<translation type="vanished">Configuration ဖိုင် မမှန်ကန်ပါ</translation>
|
||||
<translation>Configuration ဖိုင် မမှန်ကန်ပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="623"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="617"/>
|
||||
<source>Scanned %1 of %2.</source>
|
||||
<translation>%2 ၏ %1 ကို စကင်န်ဖတ်ထားသည်.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="658"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="652"/>
|
||||
<source>In the imported configuration, potentially dangerous lines were found:</source>
|
||||
<translation>တင်သွင်းသည့် configuration တွင်၊ အန္တရာယ်ရှိနိုင်သည့်စာလိုင်းများကို တွေ့ရှိခဲ့သည်:</translation>
|
||||
</message>
|
||||
@@ -275,86 +278,86 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>InstallController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="157"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="181"/>
|
||||
<source>%1 installed successfully. </source>
|
||||
<translation>%1 ကို အောင်မြင်စွာ ထည့်သွင်းပြီးပါပြီ. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="159"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="183"/>
|
||||
<source>%1 is already installed on the server. </source>
|
||||
<translation>%1 ကို ဆာဗာတွင် ထည့်သွင်းပြီးဖြစ်သည်. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="179"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="203"/>
|
||||
<source>
|
||||
Added containers that were already installed on the server</source>
|
||||
<translation>
|
||||
ဆာဗာတွင် ထည့်သွင်းပြီးသား ကွန်တိန်နာများကို ပေါင်းထည့်ပြီးပါပြီ။</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="259"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="283"/>
|
||||
<source>
|
||||
Already installed containers were found on the server. All installed containers have been added to the application</source>
|
||||
<translation>
|
||||
ထည့်သွင်းပြီးသား ကွန်တိန်နာများကို ဆာဗာပေါ်တွင် တွေ့ရှိခဲ့သည်။ ထည့်သွင်းထားသည့် ကွန်တိန်နာအားလုံးကို အပလီကေးရှင်းထဲသို့ ပေါင်းထည့်ပြီးပါပြီ။</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="517"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="541"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>ဆက်တင်များကို အောင်မြင်စွာ အပ်ဒိတ်လုပ်ပြီးပါပြီ။</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="534"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="558"/>
|
||||
<source>Server '%1' was rebooted</source>
|
||||
<translation>ဆာဗာ '%1' ကို ပြန်လည်စတင်ခဲ့သည်။</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="546"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="570"/>
|
||||
<source>Server '%1' was removed</source>
|
||||
<translation>ဆာဗာ '%1' ကို ဖယ်ရှားခဲ့သည်။</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="557"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="581"/>
|
||||
<source>All containers from server '%1' have been removed</source>
|
||||
<translation>ဆာဗာ '%1' မှ ကွန်တိန်နာအားလုံးကို ဖယ်ရှားလိုက်ပါပြီ။</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="575"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="599"/>
|
||||
<source>%1 has been removed from the server '%2'</source>
|
||||
<translation>%1 ကို ဆာဗာ '%2' မှ ဖယ်ရှားလိုက်ပါပြီ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="584"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="608"/>
|
||||
<source>Api config removed</source>
|
||||
<translation>Api config ကိုဖယ်ရှားလိုက်သည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="606"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="630"/>
|
||||
<source>%1 cached profile cleared</source>
|
||||
<translation>ကက်ရှ်လုပ်ထားတဲ့ ပရိုဖိုင် %1 ခုကို ရှင်းပြီးပါပြီ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="745"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="769"/>
|
||||
<source>Please login as the user</source>
|
||||
<translation>အသုံးပြုသူအဖြစ် log in ဝင်ရောက်ပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="773"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="797"/>
|
||||
<source>Server added successfully</source>
|
||||
<translation>ဆာဗာကို အောင်မြင်စွာ ထည့်သွင်းပြီးပါပြီ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="821"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="845"/>
|
||||
<source>%1 installed successfully.</source>
|
||||
<translation>%1 ခုကို အောင်မြင်စွာ ထည့်သွင်းပြီးပါပြီ.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="855"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="877"/>
|
||||
<source>API config reloaded</source>
|
||||
<translation>API config ကို ပြန်လည်စတင်လိုက်ပါပြီ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="859"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="881"/>
|
||||
<source>Successfully changed the country of connection to %1</source>
|
||||
<translation>ချိတ်ဆက်မှုနိုင်ငံကို %1 သို့ အောင်မြင်စွာ ပြောင်းလဲလိုက်ပါပြီ</translation>
|
||||
</message>
|
||||
@@ -398,28 +401,28 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>NotificationHandler</name>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="63"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="70"/>
|
||||
<source>AmneziaVPN</source>
|
||||
<translation>AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="65"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<source>VPN Connected</source>
|
||||
<translation>VPN ချိတ်ဆက်ထားပါပြီ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="72"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<source>VPN Disconnected</source>
|
||||
<translation>VPN ဖြုတ်လိုက်ပါပြီ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="94"/>
|
||||
<source>AmneziaVPN notification</source>
|
||||
<translation>AmneziaVPN နိုတီ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="96"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<source>Unsecured network detected: </source>
|
||||
<translation>လုံခြုံမှုမရှိသောကွန်ရက်မှန်း ထောက်လှန်းမိသည်: </translation>
|
||||
</message>
|
||||
@@ -2324,107 +2327,97 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>PageSetupWizardConfigSource</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/>
|
||||
<source>File with connection settings</source>
|
||||
<translation>ချိတ်ဆက်မှုဆက်တင်များပါဝင်သောဖိုင်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
|
||||
<source>Connection</source>
|
||||
<translation>ချိတ်ဆက်မှု</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished">ဆက်တင်များ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
|
||||
<source>Enable logs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
|
||||
<source>Support tag</source>
|
||||
<translation type="unfinished">ကူညီပံ့ပိုးမှု tag</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<source>Copied</source>
|
||||
<translation type="unfinished">ကူးယူပြီးပါပြီ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
|
||||
<source>Insert the key, add a configuration file or scan the QR-code</source>
|
||||
<translation>Key ကိုထည့်မည်၊ ဖွဲ့စည်းမှုဖိုင်တစ်ခုကိုထည့်မည် သို့မဟုတ် QR-ကုဒ်ကို စကင်န်ဖတ်မည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
|
||||
<source>Insert key</source>
|
||||
<translation>Key ကိုထည့်သွင်းမည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<source>Insert</source>
|
||||
<translation>ထည့်သွင်းမည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
|
||||
<source>Continue</source>
|
||||
<translation>ဆက်လက်လုပ်ဆောင်မည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/>
|
||||
<source>Other connection options</source>
|
||||
<translation>အခြားချိတ်ဆက်မှုရွေးချယ်စရာများ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/>
|
||||
<source>VPN by Amnezia</source>
|
||||
<translation>Amnezia မှ VPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/>
|
||||
<source>Connect to classic paid and free VPN services from Amnezia</source>
|
||||
<translation>Amnezia မှ အခပေးနှင့် အခမဲ့ မူလ VPN ဝန်ဆောင်မှုများသို့ ချိတ်ဆက်မည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/>
|
||||
<source>Self-hosted VPN</source>
|
||||
<translation>ကိုယ်တိုင် host လုပ်ထားသော VPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/>
|
||||
<source>Configure Amnezia VPN on your own server</source>
|
||||
<translation>Amnezia VPN ကို သင်၏ကိုယ်ပိုင်ဆာဗာပေါ်တွင် စီစဥ်ချိန်ညှိမည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/>
|
||||
<source>Restore from backup</source>
|
||||
<translation>အရံဖိုင်မှ ပြန်လည်ရယူမည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/>
|
||||
<source>Open backup file</source>
|
||||
<translation>အရံဖိုင်ကို ဖွင့်မည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
|
||||
<source>Backup files (*.backup)</source>
|
||||
<translation>အရံဖိုင်များ (*.backup)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/>
|
||||
<source>Open config file</source>
|
||||
<translation>config ဖိုင်ကိုဖွင့်မည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
|
||||
<source>QR code</source>
|
||||
<translation>QR-ကုဒ်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/>
|
||||
<source>I have nothing</source>
|
||||
<translation>ကျွန်ုပ်တွင်ဘာမှမရှိပါ</translation>
|
||||
</message>
|
||||
@@ -2437,12 +2430,12 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>ဆာဗာ IP လိပ်စာ [:port]</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
|
||||
<source>Continue</source>
|
||||
<translation>ဆက်လက်လုပ်ဆောင်မည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
|
||||
<source>Enter the address in the format 255.255.255.255:88</source>
|
||||
<translation>လိပ်စာကို 255.255.255.255:88 ဖော်မတ်ဖြင့် ထည့်ပါ</translation>
|
||||
</message>
|
||||
@@ -2457,42 +2450,42 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>255.255.255.255:22</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
|
||||
<source>SSH Username</source>
|
||||
<translation>SSH အသုံးပြုသူအမည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
|
||||
<source>Password or SSH private key</source>
|
||||
<translation>စကားဝှက် သိုမဟုတ် SSH private key</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
|
||||
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>သင်ထည့်သွင်းသည့်ဒေတာအားလုံးကို တင်းကြပ်လုံခြုံစွာလျှို့ဝှက်ထားမည်ဖြစ်ပြီး Amnezia သို့မဟုတ် မည်သည့်ပြင်ပအဖွဲ့အစည်းကိုမျှ မျှဝေမည် သို့မဟုတ် ထုတ်ဖော်မည်မဟုတ်ပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
|
||||
<source>How to run your VPN server</source>
|
||||
<translation>သင်၏ဆာဗာကို လည်ပတ်ပုံလည်ပတ်နည်း</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
|
||||
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
|
||||
<translation>ချိတ်ဆက်မှုဒေတာကို ဘယ်မှာရနိုင်မလဲ၊ VPS ဝယ်ယူပုံဝယ်ယူနည်းအတွက် အဆင့်ဆင့် ညွှန်ကြားချက်များ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<source>Ip address cannot be empty</source>
|
||||
<translation>IP လိပ်စာသည် ဗလာမဖြစ်ရပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
|
||||
<source>Login cannot be empty</source>
|
||||
<translation>လော့ဂ်အင်အချက်အလက်သည် ဗလာမဖြစ်ရပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
|
||||
<source>Password/private key cannot be empty</source>
|
||||
<translation>စကားဝှက်/private key သည် ဗလာမဖြစ်ရပါ</translation>
|
||||
</message>
|
||||
@@ -2812,67 +2805,62 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>ရှာဖွေမည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/>
|
||||
<source>Creation date: %1</source>
|
||||
<translation>ဖန်တီးပြုလုပ်သည့်ရက်စွဲ: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/>
|
||||
<source>Latest handshake: %1</source>
|
||||
<translation>နောက်ဆုံး handshake လုပ်ခြင်း: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/>
|
||||
<source>Data received: %1</source>
|
||||
<translation>လက်ခံရရှိသည့်ဒေတာ: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/>
|
||||
<source>Data sent: %1</source>
|
||||
<translation>ပေးပို့လိုက်သည့်ဒေတာ: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
|
||||
<source>Allowed IPs: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
|
||||
<source>Rename</source>
|
||||
<translation>အမည်ပြောင်းမည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
|
||||
<source>Client name</source>
|
||||
<translation>ကလိုင်းရင့်အမည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
|
||||
<source>Save</source>
|
||||
<translation>သိမ်းဆည်းမည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
|
||||
<source>Revoke</source>
|
||||
<translation>ပြန်ရုပ်သိမ်းမည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
|
||||
<source>Revoke the config for a user - %1?</source>
|
||||
<translation>အသုံးပြုသူ %1 အတွက် config ကို ပြန်လည်ရုပ်သိမ်းမည်လား?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<source>The user will no longer be able to connect to your server.</source>
|
||||
<translation>ဤအသုံးပြုသူသည် သင့်ဆာဗာသို့ ချိတ်ဆက်နိုင်တော့မည်မဟုတ်ပါ.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
|
||||
<source>Continue</source>
|
||||
<translation>ဆက်လက်လုပ်ဆောင်မည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
|
||||
<source>Cancel</source>
|
||||
<translation>ပယ်ဖျက်မည်</translation>
|
||||
</message>
|
||||
@@ -2959,17 +2947,17 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>PageStart</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/>
|
||||
<source>Logging was disabled after 14 days, log files were deleted</source>
|
||||
<translation>၁၄ ရက်အကြာတွင် Logging ကို ပိတ်ခဲ့သည်၊ မှတ်တမ်းဖိုင်များကို ဖျက်ပစ်လိုက်ပြီဖြစ်သည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
|
||||
<source>Settings restored from backup file</source>
|
||||
<translation>ဆက်တင်များကို အရံဖိုင်မှ ပြန်လည်ရယူပြီးပါပြီ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/>
|
||||
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -3301,17 +3289,17 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>Config တွင် ဆာဗာသို့ချိတ်ဆက်ရန်အတွက် ကွန်တိန်နာများနှင့် အထောက်အထားများ မပါဝင်ပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<location filename="../core/errorstrings.cpp" line="58"/>
|
||||
<source>Error when retrieving configuration from API</source>
|
||||
<translation>API မှ စီစဉ်သတ်မှတ်မှုကို ရယူသည့်အခါ အမှားအယွင်းဖြစ်ပေါ်နေသည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="60"/>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<source>This config has already been added to the application</source>
|
||||
<translation>ဤ config ကို အပလီကေးရှင်းထဲသို့ ထည့်သွင်းပြီးဖြစ်သည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="80"/>
|
||||
<location filename="../core/errorstrings.cpp" line="78"/>
|
||||
<source>ErrorCode: %1. </source>
|
||||
<translation>မှားယွင်းမှုကုတ်: %1. </translation>
|
||||
</message>
|
||||
@@ -3381,72 +3369,62 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>VPN pool မှားယွင်းမှု: ရရှိနိုင်သောလိပ်စာများမရှိပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="53"/>
|
||||
<source>Unable to open config file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="56"/>
|
||||
<location filename="../core/errorstrings.cpp" line="55"/>
|
||||
<source>VPN connection error</source>
|
||||
<translation>VPN ချိတ်ဆက်မှုမှားယွင်းနေပါသည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<location filename="../core/errorstrings.cpp" line="60"/>
|
||||
<source>In the response from the server, an empty config was received</source>
|
||||
<translation>ဆာဗာမှ တုံ့ပြန်မှုတွင်၊ config အလွတ်တစ်ခုကို လက်ခံရရှိခဲ့သည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<source>SSL error occurred</source>
|
||||
<translation>SSL မှားယွင်းမှုဖြစ်သွားသည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<source>Server response timeout on api request</source>
|
||||
<translation>Api တောင်းဆိုမှုတွင် ဆာဗာတုံ့ပြန်မှု အချိန်ကုန်သွားသည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="64"/>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<source>Missing AGW public key</source>
|
||||
<translation>AGW public key ပျောက်ဆုံးနေသည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="65"/>
|
||||
<source>Failed to decrypt response payload</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="68"/>
|
||||
<location filename="../core/errorstrings.cpp" line="66"/>
|
||||
<source>QFile error: The file could not be opened</source>
|
||||
<translation>QFile မှားယွင်းမှု: ဖိုင်ကို ဖွင့်၍မရပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<location filename="../core/errorstrings.cpp" line="67"/>
|
||||
<source>QFile error: An error occurred when reading from the file</source>
|
||||
<translation>QFile မှားယွင်းမှု: ဖိုင်ကိုဖတ်နေစဥ်အတွင်း မှားယွင်းမှုဖြစ်သွားသည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<location filename="../core/errorstrings.cpp" line="68"/>
|
||||
<source>QFile error: The file could not be accessed</source>
|
||||
<translation>QFile မှားယွင်းမှု: ဖိုင်ကို ဝင်၍မရပါ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<source>QFile error: An unspecified error occurred</source>
|
||||
<translation>QFile မှားယွင်းမှု: သတ်မှတ်မထားသော မှားယွင်းမှုတစ်ခု ဖြစ်ပွားခဲ့သည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="72"/>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<source>QFile error: A fatal error occurred</source>
|
||||
<translation>QFile မှားယွင်းမှု: ကြီးမားသော မှားယွင်းမှုတစ်ခု ဖြစ်ပွားခဲ့သည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="73"/>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<source>QFile error: The operation was aborted</source>
|
||||
<translation>QFile မှားယွင်းမှု: လုပ်ငန်းစဥ်ကို ဖျက်သိမ်းလိုက်ရသည်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="77"/>
|
||||
<location filename="../core/errorstrings.cpp" line="75"/>
|
||||
<source>Internal error</source>
|
||||
<translation>စက်တွင်းဖြစ်သော မှားယွင်းမှု</translation>
|
||||
</message>
|
||||
@@ -4053,7 +4031,7 @@ For more detailed information, you can
|
||||
<context>
|
||||
<name>VpnConnection</name>
|
||||
<message>
|
||||
<location filename="../vpnconnection.cpp" line="409"/>
|
||||
<location filename="../vpnconnection.cpp" line="408"/>
|
||||
<source>Mbps</source>
|
||||
<translation>Mbps</translation>
|
||||
</message>
|
||||
@@ -4127,12 +4105,12 @@ For more detailed information, you can
|
||||
<context>
|
||||
<name>main2</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="163"/>
|
||||
<location filename="../ui/qml/main2.qml" line="162"/>
|
||||
<source>Private key passphrase</source>
|
||||
<translation>ကိုယ်ပိုင် key စကားဝှက်</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="186"/>
|
||||
<location filename="../ui/qml/main2.qml" line="185"/>
|
||||
<source>Save</source>
|
||||
<translation>သိမ်းဆည်းမည်</translation>
|
||||
</message>
|
||||
|
||||
@@ -88,62 +88,62 @@
|
||||
<context>
|
||||
<name>ConnectionController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
|
||||
<source>VPN Protocols is not installed.
|
||||
Please install VPN container at first</source>
|
||||
<translation>VPN-протоколы не установлены.
|
||||
Пожалуйста, установите протокол</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
|
||||
<source>Connecting...</source>
|
||||
<translation>Подключение...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
|
||||
<source>Connected</source>
|
||||
<translation>Подключено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
|
||||
<source>Preparing...</source>
|
||||
<translation>Подготовка...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
|
||||
<source>Settings updated successfully, reconnnection...</source>
|
||||
<translation>Настройки успешно обновлены, переподключение...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>Настройки успешно обновлены</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="212"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="209"/>
|
||||
<source>The selected protocol is not supported on the current platform</source>
|
||||
<translation>Выбранный протокол не поддерживается на данном устройстве</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
|
||||
<source>unable to create configuration</source>
|
||||
<translation>не удалось создать конфигурацию</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
|
||||
<source>Reconnecting...</source>
|
||||
<translation>Переподключение...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.h" line="80"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
|
||||
<source>Connect</source>
|
||||
<translation>Подключиться</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
|
||||
<source>Disconnecting...</source>
|
||||
<translation>Отключение...</translation>
|
||||
</message>
|
||||
@@ -258,20 +258,23 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>ImportController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="87"/>
|
||||
<source>Unable to open file</source>
|
||||
<translation type="vanished">Невозможно открыть файл</translation>
|
||||
<translation>Невозможно открыть файл</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="187"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="192"/>
|
||||
<source>Invalid configuration file</source>
|
||||
<translation type="vanished">Неверный файл конфигурации</translation>
|
||||
<translation>Неверный файл конфигурации</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="623"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="617"/>
|
||||
<source>Scanned %1 of %2.</source>
|
||||
<translation>Отсканировано %1 из %2.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="658"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="652"/>
|
||||
<source>In the imported configuration, potentially dangerous lines were found:</source>
|
||||
<translation>В импортированной конфигурации были обнаружены потенциально опасные строки:</translation>
|
||||
</message>
|
||||
@@ -279,86 +282,86 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>InstallController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="157"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="181"/>
|
||||
<source>%1 installed successfully. </source>
|
||||
<translation>%1 успешно установлен. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="159"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="183"/>
|
||||
<source>%1 is already installed on the server. </source>
|
||||
<translation>%1 уже установлен на сервер. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="179"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="203"/>
|
||||
<source>
|
||||
Added containers that were already installed on the server</source>
|
||||
<translation>
|
||||
Добавлены сервисы и протоколы, которые были ранее установлены на сервер</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="259"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="283"/>
|
||||
<source>
|
||||
Already installed containers were found on the server. All installed containers have been added to the application</source>
|
||||
<translation>
|
||||
На сервере обнаружены установленные протоколы и сервисы. Все они были добавлены в приложение</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="517"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="541"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>Настройки успешно обновлены</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="534"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="558"/>
|
||||
<source>Server '%1' was rebooted</source>
|
||||
<translation>Сервер '%1' был перезагружен</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="546"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="570"/>
|
||||
<source>Server '%1' was removed</source>
|
||||
<translation>Сервер '%1' был удален</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="557"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="581"/>
|
||||
<source>All containers from server '%1' have been removed</source>
|
||||
<translation>Все протоколы и сервисы были удалены с сервера '%1'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="575"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="599"/>
|
||||
<source>%1 has been removed from the server '%2'</source>
|
||||
<translation>%1 был удален с сервера '%2'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="584"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="608"/>
|
||||
<source>Api config removed</source>
|
||||
<translation>Конфигурация API удалена</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="606"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="630"/>
|
||||
<source>%1 cached profile cleared</source>
|
||||
<translation>%1 закэшированный профиль очищен</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="745"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="769"/>
|
||||
<source>Please login as the user</source>
|
||||
<translation>Пожалуйста, войдите в систему от имени пользователя</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="773"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="797"/>
|
||||
<source>Server added successfully</source>
|
||||
<translation>Сервер успешно добавлен</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="821"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="845"/>
|
||||
<source>%1 installed successfully.</source>
|
||||
<translation>%1 успешно установлен.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="855"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="877"/>
|
||||
<source>API config reloaded</source>
|
||||
<translation>Конфигурация API перезагружена</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="859"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="881"/>
|
||||
<source>Successfully changed the country of connection to %1</source>
|
||||
<translation>Изменение страны подключения на %1</translation>
|
||||
</message>
|
||||
@@ -402,28 +405,28 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>NotificationHandler</name>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="63"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="70"/>
|
||||
<source>AmneziaVPN</source>
|
||||
<translation>AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="65"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<source>VPN Connected</source>
|
||||
<translation>VPN подключен</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="72"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<source>VPN Disconnected</source>
|
||||
<translation>VPN выключен</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="94"/>
|
||||
<source>AmneziaVPN notification</source>
|
||||
<translation>Уведомление AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="96"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<source>Unsecured network detected: </source>
|
||||
<translation>Обнаружена незащищенная сеть: </translation>
|
||||
</message>
|
||||
@@ -2502,7 +2505,7 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">Что у вас есть?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/>
|
||||
<source>File with connection settings</source>
|
||||
<translation>Файл с настройками подключения</translation>
|
||||
</message>
|
||||
@@ -2511,102 +2514,92 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">Файл с настройками подключения или резервной копией</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
|
||||
<source>Connection</source>
|
||||
<translation>Соединение</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished">Настройки</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
|
||||
<source>Enable logs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
|
||||
<source>Support tag</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<source>Copied</source>
|
||||
<translation type="unfinished">Скопировано</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
|
||||
<source>Insert the key, add a configuration file or scan the QR-code</source>
|
||||
<translation>Вставьте ключ, добавьте файл конфигурации или отсканируйте QR-код</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
|
||||
<source>Insert key</source>
|
||||
<translation>Вставьте ключ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<source>Insert</source>
|
||||
<translation>Вставить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
|
||||
<source>Continue</source>
|
||||
<translation>Продолжить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/>
|
||||
<source>Other connection options</source>
|
||||
<translation>Другие варианты подключения</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/>
|
||||
<source>VPN by Amnezia</source>
|
||||
<translation>VPN от Amnezia</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/>
|
||||
<source>Connect to classic paid and free VPN services from Amnezia</source>
|
||||
<translation>Подключайтесь к классическим платным и бесплатным VPN-сервисам от Amnezia</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/>
|
||||
<source>Self-hosted VPN</source>
|
||||
<translation>Self-hosted VPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/>
|
||||
<source>Configure Amnezia VPN on your own server</source>
|
||||
<translation>Настроить VPN на собственном сервере</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/>
|
||||
<source>Restore from backup</source>
|
||||
<translation>Восстановить из резервной копии</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/>
|
||||
<source>Open backup file</source>
|
||||
<translation>Открыть резервную копию</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
|
||||
<source>Backup files (*.backup)</source>
|
||||
<translation>Файлы резервных копий (*.backup)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/>
|
||||
<source>Open config file</source>
|
||||
<translation>Открыть файл с конфигурацией</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
|
||||
<source>QR code</source>
|
||||
<translation>QR-код</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/>
|
||||
<source>I have nothing</source>
|
||||
<translation>У меня ничего нет</translation>
|
||||
</message>
|
||||
@@ -2635,7 +2628,7 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">Password / SSH private key</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
|
||||
<source>Continue</source>
|
||||
<translation>Продолжить</translation>
|
||||
</message>
|
||||
@@ -2645,7 +2638,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation type="vanished">Все данные, которые вы вводите, останутся строго конфиденциальными и не будут переданы или раскрыты Amnezia или каким-либо третьим лицам</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
|
||||
<source>Enter the address in the format 255.255.255.255:88</source>
|
||||
<translation>Введите адрес в формате 255.255.255.255:88</translation>
|
||||
</message>
|
||||
@@ -2664,42 +2657,42 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>255.255.255.255:22</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
|
||||
<source>SSH Username</source>
|
||||
<translation>Имя пользователя SSH</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
|
||||
<source>Password or SSH private key</source>
|
||||
<translation>Пароль или закрытый ключ SSH</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
|
||||
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>Все данные, которые вы вводите, останутся строго конфиденциальными и не будут переданы или раскрыты Amnezia или каким-либо третьим лицам</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
|
||||
<source>How to run your VPN server</source>
|
||||
<translation>Как создать VPN на собственном сервере</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
|
||||
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
|
||||
<translation>Где взять данные для подключения, пошаговые инстуркции по покупке VPS</translation>
|
||||
<translation>Где взять данные для подключения, пошаговые инструкции по покупке VPS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<source>Ip address cannot be empty</source>
|
||||
<translation>Поле с IP-адресом не может быть пустым</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
|
||||
<source>Login cannot be empty</source>
|
||||
<translation>Поле с логином не может быть пустым</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
|
||||
<source>Password/private key cannot be empty</source>
|
||||
<translation>Поле с паролем/закрытым ключом не может быть пустым</translation>
|
||||
</message>
|
||||
@@ -3075,71 +3068,66 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>Поиск</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/>
|
||||
<source>Creation date: %1</source>
|
||||
<translation>Дата создания: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/>
|
||||
<source>Latest handshake: %1</source>
|
||||
<translation>Последнее рукопожатие: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/>
|
||||
<source>Data received: %1</source>
|
||||
<translation>Получено данных: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/>
|
||||
<source>Data sent: %1</source>
|
||||
<translation>Отправлено данных: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
|
||||
<source>Allowed IPs: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Creation date: </source>
|
||||
<translation type="vanished">Дата создания: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
|
||||
<source>Rename</source>
|
||||
<translation>Переименовать</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
|
||||
<source>Client name</source>
|
||||
<translation>Имя клиента</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
|
||||
<source>Save</source>
|
||||
<translation>Сохранить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
|
||||
<source>Revoke</source>
|
||||
<translation>Отозвать</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
|
||||
<source>Revoke the config for a user - %1?</source>
|
||||
<translation>Отозвать конфигурацию для пользователя - %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<source>The user will no longer be able to connect to your server.</source>
|
||||
<translation>Пользователь больше не сможет подключаться к вашему серверу.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
|
||||
<source>Continue</source>
|
||||
<translation>Продолжить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
|
||||
<source>Cancel</source>
|
||||
<translation>Отменить</translation>
|
||||
</message>
|
||||
@@ -3230,17 +3218,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<context>
|
||||
<name>PageStart</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/>
|
||||
<source>Logging was disabled after 14 days, log files were deleted</source>
|
||||
<translation>Логирование было отключено по прошествии 14 дней, файлы логов были удалены.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
|
||||
<source>Settings restored from backup file</source>
|
||||
<translation>Настройки восстановлены из бэкап файла</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/>
|
||||
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -3637,17 +3625,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>Конфигурация не содержит каких-либо контейнеров и учетных данных для подключения к серверу</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<location filename="../core/errorstrings.cpp" line="58"/>
|
||||
<source>Error when retrieving configuration from API</source>
|
||||
<translation>Ошибка при получении конфигурации из API</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="60"/>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<source>This config has already been added to the application</source>
|
||||
<translation>Данная конфигурация уже была добавлена в приложение</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="80"/>
|
||||
<location filename="../core/errorstrings.cpp" line="78"/>
|
||||
<source>ErrorCode: %1. </source>
|
||||
<translation>Код ошибки: %1. </translation>
|
||||
</message>
|
||||
@@ -3706,72 +3694,62 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>Ошибка пула VPN: нет доступных адресов</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="53"/>
|
||||
<source>Unable to open config file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="56"/>
|
||||
<location filename="../core/errorstrings.cpp" line="55"/>
|
||||
<source>VPN connection error</source>
|
||||
<translation>Ошибка VPN-соединения</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<location filename="../core/errorstrings.cpp" line="60"/>
|
||||
<source>In the response from the server, an empty config was received</source>
|
||||
<translation>В ответе от сервера была получена пустая конфигурация</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<source>SSL error occurred</source>
|
||||
<translation>Произошла ошибка SSL</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<source>Server response timeout on api request</source>
|
||||
<translation>Тайм-аут ответа сервера на запрос API</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="64"/>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<source>Missing AGW public key</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="65"/>
|
||||
<source>Failed to decrypt response payload</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="68"/>
|
||||
<location filename="../core/errorstrings.cpp" line="66"/>
|
||||
<source>QFile error: The file could not be opened</source>
|
||||
<translation>Ошибка QFile: не удалось открыть файл</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<location filename="../core/errorstrings.cpp" line="67"/>
|
||||
<source>QFile error: An error occurred when reading from the file</source>
|
||||
<translation>Ошибка QFile: произошла ошибка при чтении из файла</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<location filename="../core/errorstrings.cpp" line="68"/>
|
||||
<source>QFile error: The file could not be accessed</source>
|
||||
<translation>Ошибка QFile: не удалось получить доступ к файлу</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<source>QFile error: An unspecified error occurred</source>
|
||||
<translation>Ошибка QFile: произошла неизвестная ошибка</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="72"/>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<source>QFile error: A fatal error occurred</source>
|
||||
<translation>Ошибка QFile: произошла фатальная ошибка</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="73"/>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<source>QFile error: The operation was aborted</source>
|
||||
<translation>Ошибка QFile: операция была прервана</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="77"/>
|
||||
<location filename="../core/errorstrings.cpp" line="75"/>
|
||||
<source>Internal error</source>
|
||||
<translation>Внутренняя ошибка</translation>
|
||||
</message>
|
||||
@@ -4471,7 +4449,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin
|
||||
<context>
|
||||
<name>VpnConnection</name>
|
||||
<message>
|
||||
<location filename="../vpnconnection.cpp" line="409"/>
|
||||
<location filename="../vpnconnection.cpp" line="408"/>
|
||||
<source>Mbps</source>
|
||||
<translation>Мбит/с</translation>
|
||||
</message>
|
||||
@@ -4569,12 +4547,12 @@ This means that AmneziaWG keeps the fast performance of the original while addin
|
||||
<context>
|
||||
<name>main2</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="163"/>
|
||||
<location filename="../ui/qml/main2.qml" line="162"/>
|
||||
<source>Private key passphrase</source>
|
||||
<translation>Парольная фраза для закрытого ключа</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="186"/>
|
||||
<location filename="../ui/qml/main2.qml" line="185"/>
|
||||
<source>Save</source>
|
||||
<translation>Сохранить</translation>
|
||||
</message>
|
||||
|
||||
@@ -111,62 +111,62 @@
|
||||
<context>
|
||||
<name>ConnectionController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
|
||||
<source>VPN Protocols is not installed.
|
||||
Please install VPN container at first</source>
|
||||
<translation>VPN протоколи не встановлено.
|
||||
Будь-ласка, встановіть VPN контейнер</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
|
||||
<source>unable to create configuration</source>
|
||||
<translation>Неможливо створити конфігурацію</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
|
||||
<source>Connecting...</source>
|
||||
<translation>Підключення...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
|
||||
<source>Connected</source>
|
||||
<translation>Підключено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
|
||||
<source>Preparing...</source>
|
||||
<translation>Підготовка...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
|
||||
<source>Settings updated successfully, reconnnection...</source>
|
||||
<translation>Налаштування оновлено, підключення...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>Налаштування оновлено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="212"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="209"/>
|
||||
<source>The selected protocol is not supported on the current platform</source>
|
||||
<translation>Вибраний протокол не підтримується на цьому пристрої</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
|
||||
<source>Reconnecting...</source>
|
||||
<translation>Перепідключення...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.h" line="80"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
|
||||
<source>Connect</source>
|
||||
<translation>Підключитись</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
|
||||
<source>Disconnecting...</source>
|
||||
<translation>Відключаємось...</translation>
|
||||
</message>
|
||||
@@ -285,20 +285,23 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>ImportController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="87"/>
|
||||
<source>Unable to open file</source>
|
||||
<translation type="vanished">Неможливо відкрити файл</translation>
|
||||
<translation>Неможливо відкрити файл</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="187"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="192"/>
|
||||
<source>Invalid configuration file</source>
|
||||
<translation type="vanished">Недійсний файл конфігурації</translation>
|
||||
<translation>Недійсний файл конфігурації</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="623"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="617"/>
|
||||
<source>Scanned %1 of %2.</source>
|
||||
<translation>Відскановано %1 з %2.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="658"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="652"/>
|
||||
<source>In the imported configuration, potentially dangerous lines were found:</source>
|
||||
<translation>У імпортованій конфігурації знайдено потенційно небезпечні рядки:</translation>
|
||||
</message>
|
||||
@@ -306,85 +309,85 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>InstallController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="157"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="181"/>
|
||||
<source>%1 installed successfully. </source>
|
||||
<translation>%1 встановлено. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="159"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="183"/>
|
||||
<source>%1 is already installed on the server. </source>
|
||||
<translation>%1 вже встановлено на сервері. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="179"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="203"/>
|
||||
<source>
|
||||
Added containers that were already installed on the server</source>
|
||||
<translation>Додані сервіси і протоколи, які були раніше встановлені на сервері</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="259"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="283"/>
|
||||
<source>
|
||||
Already installed containers were found on the server. All installed containers have been added to the application</source>
|
||||
<translation>
|
||||
На сервері знайдені сервіси та протоколи, всі вони додані в застосунок</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="517"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="541"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>Налаштування оновлено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="534"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="558"/>
|
||||
<source>Server '%1' was rebooted</source>
|
||||
<translation>Сервер '%1' перезавантажено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="546"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="570"/>
|
||||
<source>Server '%1' was removed</source>
|
||||
<translation>Сервер '%1' був видалений</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="557"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="581"/>
|
||||
<source>All containers from server '%1' have been removed</source>
|
||||
<translation>Всі сервіси та протоколи були видалені з сервера '%1'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="575"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="599"/>
|
||||
<source>%1 has been removed from the server '%2'</source>
|
||||
<translation>%1 був видалений з сервера '%2'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="584"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="608"/>
|
||||
<source>Api config removed</source>
|
||||
<translation>Конфігурацію API видалено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="606"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="630"/>
|
||||
<source>%1 cached profile cleared</source>
|
||||
<translation>Кешований профіль %1 очищено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="745"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="769"/>
|
||||
<source>Please login as the user</source>
|
||||
<translation>Буль-ласка, увійдіть в систему від імені користувача</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="773"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="797"/>
|
||||
<source>Server added successfully</source>
|
||||
<translation>Сервер додано</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="821"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="845"/>
|
||||
<source>%1 installed successfully.</source>
|
||||
<translation>%1 встановлено успішно.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="855"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="877"/>
|
||||
<source>API config reloaded</source>
|
||||
<translation>Конфігурацію API перезавантажено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="859"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="881"/>
|
||||
<source>Successfully changed the country of connection to %1</source>
|
||||
<translation>Успішно змінено країну підключення на %1</translation>
|
||||
</message>
|
||||
@@ -428,28 +431,28 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>NotificationHandler</name>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="63"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="70"/>
|
||||
<source>AmneziaVPN</source>
|
||||
<translation>AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="65"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<source>VPN Connected</source>
|
||||
<translation>VPN Підключено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="72"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<source>VPN Disconnected</source>
|
||||
<translation>VPN Вимкнено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="94"/>
|
||||
<source>AmneziaVPN notification</source>
|
||||
<translation>Сповіщення AmneziaVPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="96"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<source>Unsecured network detected: </source>
|
||||
<translation>Знайдена не захищена мережа: </translation>
|
||||
</message>
|
||||
@@ -2588,7 +2591,7 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">Виберіть що у вас є</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/>
|
||||
<source>File with connection settings</source>
|
||||
<translation>Файл з налаштуваннями підключення</translation>
|
||||
</message>
|
||||
@@ -2597,102 +2600,92 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">Файл з налаштуваннями підключення або бекап</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
|
||||
<source>Connection</source>
|
||||
<translation>Підключення</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished">Налаштування</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
|
||||
<source>Enable logs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
|
||||
<source>Support tag</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<source>Copied</source>
|
||||
<translation type="unfinished">Скопійовано</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
|
||||
<source>Insert the key, add a configuration file or scan the QR-code</source>
|
||||
<translation>Вставте ключ, додайте файл конфігурації або відскануйте QR-код</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
|
||||
<source>Insert key</source>
|
||||
<translation>Вставити ключ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<source>Insert</source>
|
||||
<translation>Вставити</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
|
||||
<source>Continue</source>
|
||||
<translation>Продовжити</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/>
|
||||
<source>Other connection options</source>
|
||||
<translation>Інші параметри підключення</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/>
|
||||
<source>VPN by Amnezia</source>
|
||||
<translation>VPN від Amnezia</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/>
|
||||
<source>Connect to classic paid and free VPN services from Amnezia</source>
|
||||
<translation>Підключайтеся до звичайних платних та безкоштовних VPN-сервісів від Amnezia</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/>
|
||||
<source>Self-hosted VPN</source>
|
||||
<translation>Self-hosted VPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/>
|
||||
<source>Configure Amnezia VPN on your own server</source>
|
||||
<translation>Налаштуйте Amnezia VPN на власному сервері</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/>
|
||||
<source>Restore from backup</source>
|
||||
<translation>Відновити із бекапа</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/>
|
||||
<source>Open backup file</source>
|
||||
<translation>Відкрити бекап файл</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
|
||||
<source>Backup files (*.backup)</source>
|
||||
<translation>Файли резервної копії (*.backup)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/>
|
||||
<source>Open config file</source>
|
||||
<translation>Відкрити файл з конфігурацією</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
|
||||
<source>QR code</source>
|
||||
<translation>QR-код</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/>
|
||||
<source>I have nothing</source>
|
||||
<translation>У мене нічого нема</translation>
|
||||
</message>
|
||||
@@ -2721,7 +2714,7 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">Password / SSH private key</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
|
||||
<source>Continue</source>
|
||||
<translation>Продовжити</translation>
|
||||
</message>
|
||||
@@ -2732,7 +2725,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
і не будуть передані чи розголошені Amnezia або будь-яким третім особам</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
|
||||
<source>Enter the address in the format 255.255.255.255:88</source>
|
||||
<translation>Введіть адресу в форматі 255.255.255.255:88</translation>
|
||||
</message>
|
||||
@@ -2751,42 +2744,42 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>255.255.255.255:22</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
|
||||
<source>SSH Username</source>
|
||||
<translation>SSH Username</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
|
||||
<source>Password or SSH private key</source>
|
||||
<translation>Пароль або SSH ключ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
|
||||
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>Усі дані, які ви вводите, залишатимуться суворо конфіденційними та не будуть передані чи розголошені Amnezia або будь-яким третім особам</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
|
||||
<source>How to run your VPN server</source>
|
||||
<translation>Як запустити ваш VPN-сервер</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
|
||||
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
|
||||
<translation>Де отримати дані для підключення: покрокові інструкції з придбання VPS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<source>Ip address cannot be empty</source>
|
||||
<translation>Поле IP address не може бути пустим</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
|
||||
<source>Login cannot be empty</source>
|
||||
<translation>Поле Login не може бути пустим</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
|
||||
<source>Password/private key cannot be empty</source>
|
||||
<translation>Поле Password/Private key не може бути пустим</translation>
|
||||
</message>
|
||||
@@ -3170,71 +3163,66 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>Пошук</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/>
|
||||
<source>Creation date: %1</source>
|
||||
<translation>Дата створення: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/>
|
||||
<source>Latest handshake: %1</source>
|
||||
<translation>Останнє з'єднання: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/>
|
||||
<source>Data received: %1</source>
|
||||
<translation>Отримано даних: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/>
|
||||
<source>Data sent: %1</source>
|
||||
<translation>Відправлено даних: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
|
||||
<source>Allowed IPs: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Creation date: </source>
|
||||
<translation type="obsolete">Дата створення:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
|
||||
<source>Rename</source>
|
||||
<translation>Перейменувати</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
|
||||
<source>Client name</source>
|
||||
<translation>Назва клієнта</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
|
||||
<source>Save</source>
|
||||
<translation>Зберегти</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
|
||||
<source>Revoke</source>
|
||||
<translation>Відкликати</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
|
||||
<source>Revoke the config for a user - %1?</source>
|
||||
<translation>Відкликати доступ для користувача - %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<source>The user will no longer be able to connect to your server.</source>
|
||||
<translation>Користувач більше не зможе підключатись до вашого сервера </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
|
||||
<source>Continue</source>
|
||||
<translation>Продовжити</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
|
||||
<source>Cancel</source>
|
||||
<translation>Відмінити</translation>
|
||||
</message>
|
||||
@@ -3324,17 +3312,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<context>
|
||||
<name>PageStart</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/>
|
||||
<source>Logging was disabled after 14 days, log files were deleted</source>
|
||||
<translation>Логування було вимкнене через 14 днів, файли журналів були видалені</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
|
||||
<source>Settings restored from backup file</source>
|
||||
<translation>Відновлення налаштувань із бекап файлу</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/>
|
||||
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -3733,17 +3721,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation type="unfinished">Конфігурація не містить контейнерів і облікових даних для підключення до серверу</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<location filename="../core/errorstrings.cpp" line="58"/>
|
||||
<source>Error when retrieving configuration from API</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="60"/>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<source>This config has already been added to the application</source>
|
||||
<translation>Ця конфігурація вже була додана в застосунок</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="80"/>
|
||||
<location filename="../core/errorstrings.cpp" line="78"/>
|
||||
<source>ErrorCode: %1. </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -3802,72 +3790,62 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>VPN pool error: no available addresses</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="53"/>
|
||||
<source>Unable to open config file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="56"/>
|
||||
<location filename="../core/errorstrings.cpp" line="55"/>
|
||||
<source>VPN connection error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<location filename="../core/errorstrings.cpp" line="60"/>
|
||||
<source>In the response from the server, an empty config was received</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<source>SSL error occurred</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<source>Server response timeout on api request</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="64"/>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<source>Missing AGW public key</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="65"/>
|
||||
<source>Failed to decrypt response payload</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="68"/>
|
||||
<location filename="../core/errorstrings.cpp" line="66"/>
|
||||
<source>QFile error: The file could not be opened</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<location filename="../core/errorstrings.cpp" line="67"/>
|
||||
<source>QFile error: An error occurred when reading from the file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<location filename="../core/errorstrings.cpp" line="68"/>
|
||||
<source>QFile error: The file could not be accessed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<source>QFile error: An unspecified error occurred</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="72"/>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<source>QFile error: A fatal error occurred</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="73"/>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<source>QFile error: The operation was aborted</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="77"/>
|
||||
<location filename="../core/errorstrings.cpp" line="75"/>
|
||||
<source>Internal error</source>
|
||||
<translation>Internal error</translation>
|
||||
</message>
|
||||
@@ -4548,7 +4526,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin
|
||||
<context>
|
||||
<name>VpnConnection</name>
|
||||
<message>
|
||||
<location filename="../vpnconnection.cpp" line="409"/>
|
||||
<location filename="../vpnconnection.cpp" line="408"/>
|
||||
<source>Mbps</source>
|
||||
<translation>Mbps</translation>
|
||||
</message>
|
||||
@@ -4646,12 +4624,12 @@ This means that AmneziaWG keeps the fast performance of the original while addin
|
||||
<context>
|
||||
<name>main2</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="163"/>
|
||||
<location filename="../ui/qml/main2.qml" line="162"/>
|
||||
<source>Private key passphrase</source>
|
||||
<translation>Пароль для особистого ключа</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="186"/>
|
||||
<location filename="../ui/qml/main2.qml" line="185"/>
|
||||
<source>Save</source>
|
||||
<translation>Зберегти</translation>
|
||||
</message>
|
||||
|
||||
@@ -89,60 +89,60 @@
|
||||
<name>ConnectionController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.h" line="80"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
|
||||
<source>Connect</source>
|
||||
<translation>جوڑنا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="212"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="209"/>
|
||||
<source>The selected protocol is not supported on the current platform</source>
|
||||
<translation>منتخب کردہ پروٹوکول موجودہ پلیٹ فارم پر تعاون یافتہ نہیں ہے</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
|
||||
<source>VPN Protocols is not installed.
|
||||
Please install VPN container at first</source>
|
||||
<translation>وی پی این پروٹوکول انسٹال نہیں ہے,براہ کرم پہلےوی پی این کنٹینر انسٹال کریں</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
|
||||
<source>unable to create configuration</source>
|
||||
<translation>تشکیل تیار کرنے میں ناکام</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
|
||||
<source>Connecting...</source>
|
||||
<translation>جوڑاجارھاھے....</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
|
||||
<source>Connected</source>
|
||||
<translation>جوڑاجارھاھے</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
|
||||
<source>Reconnecting...</source>
|
||||
<translation>دوبارہ جوڑنےکی کوشش...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
|
||||
<source>Disconnecting...</source>
|
||||
<translation>منقطع کرنا...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
|
||||
<source>Preparing...</source>
|
||||
<translation>تیاری کیا جا رہا ہے...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
|
||||
<source>Settings updated successfully, reconnnection...</source>
|
||||
<translation>ترتیب ک ھوگی،دوبارہ جوڑنےکی کوشش...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>دوبارہ ترتیب تاذہ کامیاب</translation>
|
||||
</message>
|
||||
@@ -252,20 +252,23 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>ImportController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="87"/>
|
||||
<source>Unable to open file</source>
|
||||
<translation type="vanished">فائل کو کھولنے سے قاصر ہے</translation>
|
||||
<translation>فائل کو کھولنے سے قاصر ہے</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="187"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="192"/>
|
||||
<source>Invalid configuration file</source>
|
||||
<translation type="vanished">غلط کنفیگریشن فائل</translation>
|
||||
<translation>غلط کنفیگریشن فائل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="623"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="617"/>
|
||||
<source>Scanned %1 of %2.</source>
|
||||
<translation>سکین%1 کی%2.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="658"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="652"/>
|
||||
<source>In the imported configuration, potentially dangerous lines were found:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -273,86 +276,86 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>InstallController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="157"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="181"/>
|
||||
<source>%1 installed successfully. </source>
|
||||
<translation>%1 کامیابی سےنصب. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="159"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="183"/>
|
||||
<source>%1 is already installed on the server. </source>
|
||||
<translation>%1 پہلے ہی سرور پر انسٹال ہے. </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="179"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="203"/>
|
||||
<source>
|
||||
Added containers that were already installed on the server</source>
|
||||
<translation>
|
||||
وہ کنٹینرز شامل کیے گئے جو پہلے سے سرور پر نصب تھے</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="259"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="283"/>
|
||||
<source>
|
||||
Already installed containers were found on the server. All installed containers have been added to the application</source>
|
||||
<translation>
|
||||
سرور پر پہلے سے نصب کنٹینرز پائے گئے۔ تمام نصب کنٹینرز کو ایپلی کیشن میں شامل کر دیا گیا ہے</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="517"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="541"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>ترتیب کامیابی کے ساتھ اپ ڈیٹ ہو گئی</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="534"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="558"/>
|
||||
<source>Server '%1' was rebooted</source>
|
||||
<translation>سرور %1 دوبارہ چالو کیا گیا تھا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="546"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="570"/>
|
||||
<source>Server '%1' was removed</source>
|
||||
<translation>سرور %1 ہٹا دیا گیا تھا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="557"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="581"/>
|
||||
<source>All containers from server '%1' have been removed</source>
|
||||
<translation>سرور '%1' سے تمام کنٹینرز ہٹا دیے گئے ہیں</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="575"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="599"/>
|
||||
<source>%1 has been removed from the server '%2'</source>
|
||||
<translation>سرور '%2' سے %1 ہٹا دیا گیا ہے</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="584"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="608"/>
|
||||
<source>Api config removed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="606"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="630"/>
|
||||
<source>%1 cached profile cleared</source>
|
||||
<translation>%1 کیش کردہ پروفائل ختم کر دی گئی</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="745"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="769"/>
|
||||
<source>Please login as the user</source>
|
||||
<translation>براہ کرم صارف کے طور پر لاگ ان کریں</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="773"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="797"/>
|
||||
<source>Server added successfully</source>
|
||||
<translation>سرور کامیابی سے شامل کیا گیا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="821"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="845"/>
|
||||
<source>%1 installed successfully.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="855"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="877"/>
|
||||
<source>API config reloaded</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="859"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="881"/>
|
||||
<source>Successfully changed the country of connection to %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -396,30 +399,30 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>NotificationHandler</name>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="63"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="70"/>
|
||||
<source>AmneziaVPN</source>
|
||||
<translation>The translation of "AmneziaVPN" in Urdu would be:
|
||||
|
||||
امنیزیا وی پی ای</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="65"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<source>VPN Connected</source>
|
||||
<translation>وی پی این متصل ہوگیا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="72"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<source>VPN Disconnected</source>
|
||||
<translation>وی پی این منقطع ہوگیا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="94"/>
|
||||
<source>AmneziaVPN notification</source>
|
||||
<translation>امنیزیا وی پی این کی اطلاعات</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="96"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<source>Unsecured network detected: </source>
|
||||
<translation>غیر محفوظ نیٹ ورک کا پتہ لگایا گیا ہے: </translation>
|
||||
</message>
|
||||
@@ -2383,107 +2386,97 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation type="vanished">کنکشن کی ترتیبات یا بیک اپ والی فائل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
|
||||
<source>Connection</source>
|
||||
<translation type="unfinished">کنکشن</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished">ترتیبات</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
|
||||
<source>Enable logs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
|
||||
<source>Support tag</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<source>Copied</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
|
||||
<source>Insert the key, add a configuration file or scan the QR-code</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
|
||||
<source>Insert key</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<source>Insert</source>
|
||||
<translation type="unfinished">داخل کریں</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
|
||||
<source>Continue</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/>
|
||||
<source>Other connection options</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/>
|
||||
<source>VPN by Amnezia</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/>
|
||||
<source>Connect to classic paid and free VPN services from Amnezia</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/>
|
||||
<source>Self-hosted VPN</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/>
|
||||
<source>Configure Amnezia VPN on your own server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/>
|
||||
<source>Restore from backup</source>
|
||||
<translation type="unfinished">بیک اپ سے بحال کریں</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/>
|
||||
<source>Open backup file</source>
|
||||
<translation type="unfinished">بیک اپ فائل کو کھولیں</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
|
||||
<source>Backup files (*.backup)</source>
|
||||
<translation type="unfinished">بیک اپ فائلیں (*.backup)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/>
|
||||
<source>File with connection settings</source>
|
||||
<translation>کنکشن کی ترتیبات والی فائل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/>
|
||||
<source>Open config file</source>
|
||||
<translation>کنفیگ فائل کو کھولیں</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
|
||||
<source>QR code</source>
|
||||
<translation>QR کوڈ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/>
|
||||
<source>I have nothing</source>
|
||||
<translation type="unfinished">میرے پاس کچھ نہیں ہے</translation>
|
||||
</message>
|
||||
@@ -2505,12 +2498,12 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>سرور آئی پی پتہ [:پورٹ]</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
|
||||
<source>Continue</source>
|
||||
<translation>براہ کرم جاری رکھیں</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
|
||||
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>آپ جو ڈیٹا داخل کریں گے وہ بالکل خفیہ رہے گا اور نہ تو امنیزیا یا کسی تیسری شخصیت کے ساتھ اشتراک کیا جائے گا</translation>
|
||||
</message>
|
||||
@@ -2520,42 +2513,42 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
|
||||
<source>SSH Username</source>
|
||||
<translation>ایس ایس ایچ صارف نام</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
|
||||
<source>Password or SSH private key</source>
|
||||
<translation>پاس ورڈ یا SSH نجی کلید</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
|
||||
<source>How to run your VPN server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
|
||||
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<source>Ip address cannot be empty</source>
|
||||
<translation>آئی پی پتہ خالی نہیں ہو سکتا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
|
||||
<source>Enter the address in the format 255.255.255.255:88</source>
|
||||
<translation>ایڈریس درج کریں فارمیٹ 255.255.255.255:88</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
|
||||
<source>Login cannot be empty</source>
|
||||
<translation>لاگ ان نام خالی نہیں ہو سکتا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
|
||||
<source>Password/private key cannot be empty</source>
|
||||
<translation>پاس ورڈ یا نجی کلید خالی نہیں ہو سکتی</translation>
|
||||
</message>
|
||||
@@ -2868,71 +2861,66 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>تلاش</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/>
|
||||
<source>Creation date: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/>
|
||||
<source>Latest handshake: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/>
|
||||
<source>Data received: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/>
|
||||
<source>Data sent: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
|
||||
<source>Allowed IPs: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Creation date: </source>
|
||||
<translation type="vanished">تخلیق کی تاریخ: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
|
||||
<source>Rename</source>
|
||||
<translation>نام تبدیل</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
|
||||
<source>Client name</source>
|
||||
<translation>کلائنٹ کا نام</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
|
||||
<source>Save</source>
|
||||
<translation>محفوظ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
|
||||
<source>Revoke</source>
|
||||
<translation>واپس لین</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
|
||||
<source>Revoke the config for a user - %1?</source>
|
||||
<translation>کیا آپ مستعمل کے لئے کنفیگ کو واپس لینا چاہتے ہیں - %1؟</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<source>The user will no longer be able to connect to your server.</source>
|
||||
<translation>صارف آپ کے سرور سے متصل ہونے کا اختیار نہیں رہے گا.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
|
||||
<source>Continue</source>
|
||||
<translation>جاری رکھیں</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
|
||||
<source>Cancel</source>
|
||||
<translation>منسوخ</translation>
|
||||
</message>
|
||||
@@ -3050,17 +3038,17 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>PageStart</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/>
|
||||
<source>Logging was disabled after 14 days, log files were deleted</source>
|
||||
<translation>لاگنگ کو 14 دنوں کے بعد غیر فعال کر دیا گیا، لاگ فائلوں کو حذف کر دیا گیا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
|
||||
<source>Settings restored from backup file</source>
|
||||
<translation type="unfinished">ترتیبات بیک اپ فائل سے بحال کردی گئی ہیں</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/>
|
||||
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -3399,22 +3387,22 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>سرور سے منسلک ہونے کا ٹائم آؤٹ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="56"/>
|
||||
<location filename="../core/errorstrings.cpp" line="55"/>
|
||||
<source>VPN connection error</source>
|
||||
<translation>VPN کنکشن کی خرابی</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<location filename="../core/errorstrings.cpp" line="58"/>
|
||||
<source>Error when retrieving configuration from API</source>
|
||||
<translation>آپی سے کنفیگریشن بازیافت کرتے وقت خرابی</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="60"/>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<source>This config has already been added to the application</source>
|
||||
<translation>یہ تشکیل پہلے ہی ایپلی کیشن میں شامل کی جا چکی ہے</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="80"/>
|
||||
<location filename="../core/errorstrings.cpp" line="78"/>
|
||||
<source>ErrorCode: %1. </source>
|
||||
<translation>ایرر کوڈ: %1. </translation>
|
||||
</message>
|
||||
@@ -3489,67 +3477,57 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation>ترتیب میں سرور سے منسلک ہونے کے لیے کوئی کنٹینرز اور اسناد نہیں ہیں</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="53"/>
|
||||
<source>Unable to open config file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<location filename="../core/errorstrings.cpp" line="60"/>
|
||||
<source>In the response from the server, an empty config was received</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<source>SSL error occurred</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<source>Server response timeout on api request</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="64"/>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<source>Missing AGW public key</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="65"/>
|
||||
<source>Failed to decrypt response payload</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="68"/>
|
||||
<location filename="../core/errorstrings.cpp" line="66"/>
|
||||
<source>QFile error: The file could not be opened</source>
|
||||
<translation>QFile کی خرابی: فائل کو نہیں کھولا جا سکا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<location filename="../core/errorstrings.cpp" line="67"/>
|
||||
<source>QFile error: An error occurred when reading from the file</source>
|
||||
<translation>کیو فائل کی خرابی: فائل سے پڑھتے وقت ایک خرابی پیش آگئی</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<location filename="../core/errorstrings.cpp" line="68"/>
|
||||
<source>QFile error: The file could not be accessed</source>
|
||||
<translation>QFile کی خرابی: فائل تک رسائی نہیں ہو سکی</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<source>QFile error: An unspecified error occurred</source>
|
||||
<translation>کیو فائل میں خرابی: ایک غیر متعینہ خرابی پیش آگئی</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="72"/>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<source>QFile error: A fatal error occurred</source>
|
||||
<translation>کیو فائل میں خرابی: ایک مہلک خرابی پیش آگئی</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="73"/>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<source>QFile error: The operation was aborted</source>
|
||||
<translation>کیو فائل کی خرابی: آپریشن روک دیا گیا تھا</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="77"/>
|
||||
<location filename="../core/errorstrings.cpp" line="75"/>
|
||||
<source>Internal error</source>
|
||||
<translation>داخلی خامی</translation>
|
||||
</message>
|
||||
@@ -4090,7 +4068,7 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||
<context>
|
||||
<name>VpnConnection</name>
|
||||
<message>
|
||||
<location filename="../vpnconnection.cpp" line="409"/>
|
||||
<location filename="../vpnconnection.cpp" line="408"/>
|
||||
<source>Mbps</source>
|
||||
<translation>ایم بی پی ایس</translation>
|
||||
</message>
|
||||
@@ -4176,12 +4154,12 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||
<context>
|
||||
<name>main2</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="163"/>
|
||||
<location filename="../ui/qml/main2.qml" line="162"/>
|
||||
<source>Private key passphrase</source>
|
||||
<translation>نجی کلید پاس فریز</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="186"/>
|
||||
<location filename="../ui/qml/main2.qml" line="185"/>
|
||||
<source>Save</source>
|
||||
<translation>محفوظ کریں</translation>
|
||||
</message>
|
||||
|
||||
@@ -89,60 +89,60 @@
|
||||
<name>ConnectionController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.h" line="80"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
|
||||
<source>Connect</source>
|
||||
<translation>连接</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
|
||||
<source>VPN Protocols is not installed.
|
||||
Please install VPN container at first</source>
|
||||
<translation>请先安装VPN协议</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
|
||||
<source>Connecting...</source>
|
||||
<translation>连接中</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
|
||||
<source>Connected</source>
|
||||
<translation>已连接</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
|
||||
<source>Reconnecting...</source>
|
||||
<translation>重连中</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
|
||||
<source>Disconnecting...</source>
|
||||
<translation>断开中</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
|
||||
<source>Preparing...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
|
||||
<source>Settings updated successfully, reconnnection...</source>
|
||||
<translation>配置已更新, 重连中...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>配置更新成功</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="212"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="209"/>
|
||||
<source>The selected protocol is not supported on the current platform</source>
|
||||
<translation type="unfinished">当前平台不支持所选协议</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
|
||||
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
|
||||
<source>unable to create configuration</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -257,12 +257,23 @@ Can't be disabled for current server</source>
|
||||
<context>
|
||||
<name>ImportController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="623"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="87"/>
|
||||
<source>Unable to open file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="187"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="192"/>
|
||||
<source>Invalid configuration file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="617"/>
|
||||
<source>Scanned %1 of %2.</source>
|
||||
<translation>扫描 %1 of %2.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/importController.cpp" line="658"/>
|
||||
<location filename="../ui/controllers/importController.cpp" line="652"/>
|
||||
<source>In the imported configuration, potentially dangerous lines were found:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -278,75 +289,75 @@ Can't be disabled for current server</source>
|
||||
<translation type="obsolete"> 已安装在服务器上</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="157"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="181"/>
|
||||
<source>%1 installed successfully. </source>
|
||||
<translation>%1 安装成功。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="159"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="183"/>
|
||||
<source>%1 is already installed on the server. </source>
|
||||
<translation>服务器上已经安装 %1。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="179"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="203"/>
|
||||
<source>
|
||||
Added containers that were already installed on the server</source>
|
||||
<translation>添加已安装在服务器上的容器</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="259"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="283"/>
|
||||
<source>
|
||||
Already installed containers were found on the server. All installed containers have been added to the application</source>
|
||||
<translation>
|
||||
在服务上发现已经安装协议并添加至应用</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="517"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="541"/>
|
||||
<source>Settings updated successfully</source>
|
||||
<translation>配置更新成功</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="534"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="558"/>
|
||||
<source>Server '%1' was rebooted</source>
|
||||
<translation>服务器 '%1' 已重新启动</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="546"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="570"/>
|
||||
<source>Server '%1' was removed</source>
|
||||
<translation>已移除服务器 '%1'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="557"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="581"/>
|
||||
<source>All containers from server '%1' have been removed</source>
|
||||
<translation>服务器 '%1' 的所有容器已移除</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="575"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="599"/>
|
||||
<source>%1 has been removed from the server '%2'</source>
|
||||
<translation>%1 已从服务器 '%2' 上移除</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="584"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="608"/>
|
||||
<source>Api config removed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="606"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="630"/>
|
||||
<source>%1 cached profile cleared</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="821"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="845"/>
|
||||
<source>%1 installed successfully.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="855"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="877"/>
|
||||
<source>API config reloaded</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="859"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="881"/>
|
||||
<source>Successfully changed the country of connection to %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -367,12 +378,12 @@ Already installed containers were found on the server. All installed containers
|
||||
<translation type="obsolete"> 协议已从</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="745"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="769"/>
|
||||
<source>Please login as the user</source>
|
||||
<translation>请以用户身份登录</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/installController.cpp" line="773"/>
|
||||
<location filename="../ui/controllers/installController.cpp" line="797"/>
|
||||
<source>Server added successfully</source>
|
||||
<translation>增加服务器成功</translation>
|
||||
</message>
|
||||
@@ -416,28 +427,28 @@ Already installed containers were found on the server. All installed containers
|
||||
<context>
|
||||
<name>NotificationHandler</name>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="63"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="70"/>
|
||||
<source>AmneziaVPN</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="65"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="64"/>
|
||||
<source>VPN Connected</source>
|
||||
<translation>已连接到VPN</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="72"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="71"/>
|
||||
<source>VPN Disconnected</source>
|
||||
<translation>已从VPN断开</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="94"/>
|
||||
<source>AmneziaVPN notification</source>
|
||||
<translation>AmneziaVPN 提示</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/notificationhandler.cpp" line="96"/>
|
||||
<location filename="../ui/notificationhandler.cpp" line="95"/>
|
||||
<source>Unsecured network detected: </source>
|
||||
<translation>发现不安全网络</translation>
|
||||
</message>
|
||||
@@ -2538,107 +2549,97 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">包含连接配置或备份的文件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
|
||||
<source>Connection</source>
|
||||
<translation type="unfinished">连接</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished">设置</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
|
||||
<source>Enable logs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
|
||||
<source>Support tag</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<source>Copied</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
|
||||
<source>Insert the key, add a configuration file or scan the QR-code</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
|
||||
<source>Insert key</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
|
||||
<source>Insert</source>
|
||||
<translation type="unfinished">插入</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
|
||||
<source>Continue</source>
|
||||
<translation type="unfinished">继续</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/>
|
||||
<source>Other connection options</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/>
|
||||
<source>VPN by Amnezia</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/>
|
||||
<source>Connect to classic paid and free VPN services from Amnezia</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/>
|
||||
<source>Self-hosted VPN</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/>
|
||||
<source>Configure Amnezia VPN on your own server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/>
|
||||
<source>Restore from backup</source>
|
||||
<translation type="unfinished">从备份还原</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/>
|
||||
<source>Open backup file</source>
|
||||
<translation type="unfinished">打开备份文件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
|
||||
<source>Backup files (*.backup)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/>
|
||||
<source>File with connection settings</source>
|
||||
<translation>包含连接配置的文件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/>
|
||||
<source>Open config file</source>
|
||||
<translation>打开配置文件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
|
||||
<source>QR code</source>
|
||||
<translation>二维码</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/>
|
||||
<source>I have nothing</source>
|
||||
<translation type="unfinished">我没有</translation>
|
||||
</message>
|
||||
@@ -2672,12 +2673,12 @@ It's okay as long as it's from someone you trust.</source>
|
||||
<translation type="vanished">密码 或 私钥</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
|
||||
<source>Continue</source>
|
||||
<translation>继续</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
|
||||
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>您输入的所有数据将严格保密,不会与 Amnezia 或任何第三方共享或披露</translation>
|
||||
</message>
|
||||
@@ -2693,42 +2694,42 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
|
||||
<source>SSH Username</source>
|
||||
<translation>SSH 用户名</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
|
||||
<source>Password or SSH private key</source>
|
||||
<translation>密码或 SSH 私钥</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
|
||||
<source>How to run your VPN server</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
|
||||
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<source>Ip address cannot be empty</source>
|
||||
<translation>IP不能为空</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
|
||||
<source>Enter the address in the format 255.255.255.255:88</source>
|
||||
<translation>按照这种格式输入 255.255.255.255:88</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
|
||||
<source>Login cannot be empty</source>
|
||||
<translation>账号不能为空</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
|
||||
<source>Password/private key cannot be empty</source>
|
||||
<translation>密码或私钥不能为空</translation>
|
||||
</message>
|
||||
@@ -3066,71 +3067,66 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation>搜索</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/>
|
||||
<source>Creation date: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/>
|
||||
<source>Latest handshake: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/>
|
||||
<source>Data received: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/>
|
||||
<source>Data sent: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
|
||||
<source>Allowed IPs: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Creation date: </source>
|
||||
<translation type="vanished">创建日期: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
|
||||
<source>Rename</source>
|
||||
<translation>重新命名</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
|
||||
<source>Client name</source>
|
||||
<translation>客户名称</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
|
||||
<source>Save</source>
|
||||
<translation>保存</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
|
||||
<source>Revoke</source>
|
||||
<translation>撤销</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
|
||||
<source>Revoke the config for a user - %1?</source>
|
||||
<translation>撤销用户的配置- %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
|
||||
<source>The user will no longer be able to connect to your server.</source>
|
||||
<translation>该用户将无法再连接到您的服务器.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
|
||||
<source>Continue</source>
|
||||
<translation>继续</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
|
||||
<source>Cancel</source>
|
||||
<translation>取消</translation>
|
||||
</message>
|
||||
@@ -3287,17 +3283,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<context>
|
||||
<name>PageStart</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/>
|
||||
<source>Logging was disabled after 14 days, log files were deleted</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
|
||||
<source>Settings restored from backup file</source>
|
||||
<translation type="unfinished">从备份文件还原配置</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
|
||||
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/>
|
||||
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@@ -3650,11 +3646,6 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<source>SCP error: Generic failure</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="53"/>
|
||||
<source>Unable to open config file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sftp error: End-of-file encountered</source>
|
||||
<translation type="vanished">Sftp错误: End-of-file encountered</translation>
|
||||
@@ -3708,77 +3699,72 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation type="vanished">Sftp 错误: 远程驱动器中没有媒介</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="56"/>
|
||||
<location filename="../core/errorstrings.cpp" line="55"/>
|
||||
<source>VPN connection error</source>
|
||||
<translation>VPN 连接错误</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<location filename="../core/errorstrings.cpp" line="58"/>
|
||||
<source>Error when retrieving configuration from API</source>
|
||||
<translation>从 API 检索配置时出错</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="60"/>
|
||||
<location filename="../core/errorstrings.cpp" line="59"/>
|
||||
<source>This config has already been added to the application</source>
|
||||
<translation>该配置已添加到应用程序中</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<location filename="../core/errorstrings.cpp" line="60"/>
|
||||
<source>In the response from the server, an empty config was received</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<location filename="../core/errorstrings.cpp" line="61"/>
|
||||
<source>SSL error occurred</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<location filename="../core/errorstrings.cpp" line="62"/>
|
||||
<source>Server response timeout on api request</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="64"/>
|
||||
<location filename="../core/errorstrings.cpp" line="63"/>
|
||||
<source>Missing AGW public key</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="65"/>
|
||||
<source>Failed to decrypt response payload</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="68"/>
|
||||
<location filename="../core/errorstrings.cpp" line="66"/>
|
||||
<source>QFile error: The file could not be opened</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<location filename="../core/errorstrings.cpp" line="67"/>
|
||||
<source>QFile error: An error occurred when reading from the file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<location filename="../core/errorstrings.cpp" line="68"/>
|
||||
<source>QFile error: The file could not be accessed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<location filename="../core/errorstrings.cpp" line="69"/>
|
||||
<source>QFile error: An unspecified error occurred</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="72"/>
|
||||
<location filename="../core/errorstrings.cpp" line="70"/>
|
||||
<source>QFile error: A fatal error occurred</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="73"/>
|
||||
<location filename="../core/errorstrings.cpp" line="71"/>
|
||||
<source>QFile error: The operation was aborted</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="80"/>
|
||||
<location filename="../core/errorstrings.cpp" line="78"/>
|
||||
<source>ErrorCode: %1. </source>
|
||||
<translation>错误代码: %1. </translation>
|
||||
</message>
|
||||
@@ -3846,7 +3832,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
|
||||
<translation type="vanished">该配置不包含任何用于连接到服务器的容器和凭据。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="77"/>
|
||||
<location filename="../core/errorstrings.cpp" line="75"/>
|
||||
<source>Internal error</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
@@ -4526,7 +4512,7 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||
<context>
|
||||
<name>VpnConnection</name>
|
||||
<message>
|
||||
<location filename="../vpnconnection.cpp" line="409"/>
|
||||
<location filename="../vpnconnection.cpp" line="408"/>
|
||||
<source>Mbps</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
@@ -4624,12 +4610,12 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||
<context>
|
||||
<name>main2</name>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="163"/>
|
||||
<location filename="../ui/qml/main2.qml" line="162"/>
|
||||
<source>Private key passphrase</source>
|
||||
<translation>私钥密码</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/main2.qml" line="186"/>
|
||||
<location filename="../ui/qml/main2.qml" line="185"/>
|
||||
<source>Save</source>
|
||||
<translation>保存</translation>
|
||||
</message>
|
||||
|
||||
@@ -55,7 +55,7 @@ void ConnectionController::openConnection()
|
||||
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
||||
emit updateApiConfigFromGateway();
|
||||
} else if (configVersion && m_serversModel->isApiKeyExpired(serverIndex)) {
|
||||
qDebug() << "attempt to update api config by end_date event";
|
||||
qDebug() << "attempt to update api config by expires_at event";
|
||||
if (configVersion == ApiConfigSources::Telegram) {
|
||||
emit updateApiConfigFromTelegram();
|
||||
} else {
|
||||
|
||||
@@ -121,9 +121,8 @@ ErrorCode ExportController::generateNativeConfig(const DockerContainer container
|
||||
|
||||
jsonNativeConfig = QJsonDocument::fromJson(protocolConfigString.toUtf8()).object();
|
||||
|
||||
if (protocol == Proto::OpenVpn || protocol == Proto::WireGuard || protocol == Proto::Awg) {
|
||||
auto clientId = jsonNativeConfig.value(config_key::clientId).toString();
|
||||
errorCode = m_clientManagementModel->appendClient(clientId, clientName, container, credentials, serverController);
|
||||
if (protocol == Proto::OpenVpn || protocol == Proto::WireGuard || protocol == Proto::Awg || protocol == Proto::Xray) {
|
||||
errorCode = m_clientManagementModel->appendClient(jsonNativeConfig, clientName, container, credentials, serverController);
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
@@ -248,10 +247,10 @@ void ExportController::generateCloakConfig()
|
||||
emit exportConfigChanged();
|
||||
}
|
||||
|
||||
void ExportController::generateXrayConfig()
|
||||
void ExportController::generateXrayConfig(const QString &clientName)
|
||||
{
|
||||
QJsonObject nativeConfig;
|
||||
ErrorCode errorCode = generateNativeConfig(DockerContainer::Xray, "", Proto::Xray, nativeConfig);
|
||||
ErrorCode errorCode = generateNativeConfig(DockerContainer::Xray, clientName, Proto::Xray, nativeConfig);
|
||||
if (errorCode) {
|
||||
emit exportErrorOccurred(errorCode);
|
||||
return;
|
||||
|
||||
@@ -28,7 +28,7 @@ public slots:
|
||||
void generateAwgConfig(const QString &clientName);
|
||||
void generateShadowSocksConfig();
|
||||
void generateCloakConfig();
|
||||
void generateXrayConfig();
|
||||
void generateXrayConfig(const QString &clientName);
|
||||
|
||||
QString getConfig();
|
||||
QString getNativeConfigString();
|
||||
|
||||
210
client/ui/controllers/focusController.cpp
Normal file
@@ -0,0 +1,210 @@
|
||||
#include "focusController.h"
|
||||
#include "utils/qmlUtils.h"
|
||||
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QQuickWindow>
|
||||
|
||||
FocusController::FocusController(QQmlApplicationEngine *engine, QObject *parent)
|
||||
: QObject { parent },
|
||||
m_engine { engine },
|
||||
m_focusChain {},
|
||||
m_focusedItem { nullptr },
|
||||
m_rootObjects {},
|
||||
m_defaultFocusItem { QSharedPointer<QQuickItem>() },
|
||||
m_lvfc { nullptr }
|
||||
{
|
||||
QObject::connect(m_engine.get(), &QQmlApplicationEngine::objectCreated, this,
|
||||
[this](QObject *object, const QUrl &url) {
|
||||
QQuickItem *newDefaultFocusItem = object->findChild<QQuickItem *>("defaultFocusItem");
|
||||
if (newDefaultFocusItem && m_defaultFocusItem != newDefaultFocusItem) {
|
||||
m_defaultFocusItem.reset(newDefaultFocusItem);
|
||||
}
|
||||
});
|
||||
|
||||
QObject::connect(this, &FocusController::focusedItemChanged, this,
|
||||
[this]() { m_focusedItem->forceActiveFocus(Qt::TabFocusReason); });
|
||||
}
|
||||
|
||||
void FocusController::nextKeyTabItem()
|
||||
{
|
||||
nextItem(Direction::Forward);
|
||||
}
|
||||
|
||||
void FocusController::previousKeyTabItem()
|
||||
{
|
||||
nextItem(Direction::Backward);
|
||||
}
|
||||
|
||||
void FocusController::nextKeyUpItem()
|
||||
{
|
||||
nextItem(Direction::Backward);
|
||||
}
|
||||
|
||||
void FocusController::nextKeyDownItem()
|
||||
{
|
||||
nextItem(Direction::Forward);
|
||||
}
|
||||
|
||||
void FocusController::nextKeyLeftItem()
|
||||
{
|
||||
nextItem(Direction::Backward);
|
||||
}
|
||||
|
||||
void FocusController::nextKeyRightItem()
|
||||
{
|
||||
nextItem(Direction::Forward);
|
||||
}
|
||||
|
||||
void FocusController::setFocusItem(QQuickItem *item)
|
||||
{
|
||||
if (m_focusedItem != item) {
|
||||
m_focusedItem = item;
|
||||
}
|
||||
emit focusedItemChanged();
|
||||
}
|
||||
|
||||
void FocusController::setFocusOnDefaultItem()
|
||||
{
|
||||
setFocusItem(m_defaultFocusItem.get());
|
||||
}
|
||||
|
||||
void FocusController::pushRootObject(QObject *object)
|
||||
{
|
||||
m_rootObjects.push(object);
|
||||
dropListView();
|
||||
// setFocusOnDefaultItem();
|
||||
}
|
||||
|
||||
void FocusController::dropRootObject(QObject *object)
|
||||
{
|
||||
if (m_rootObjects.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_rootObjects.top() == object) {
|
||||
m_rootObjects.pop();
|
||||
dropListView();
|
||||
setFocusOnDefaultItem();
|
||||
} else {
|
||||
qWarning() << "===>> TRY TO DROP WRONG ROOT OBJECT: " << m_rootObjects.top() << " SHOULD BE: " << object;
|
||||
}
|
||||
}
|
||||
|
||||
void FocusController::resetRootObject()
|
||||
{
|
||||
m_rootObjects.clear();
|
||||
}
|
||||
|
||||
void FocusController::reload(Direction direction)
|
||||
{
|
||||
m_focusChain.clear();
|
||||
|
||||
QObject *rootObject = (m_rootObjects.empty() ? m_engine->rootObjects().value(0) : m_rootObjects.top());
|
||||
|
||||
if (!rootObject) {
|
||||
qCritical() << "No ROOT OBJECT found!";
|
||||
resetRootObject();
|
||||
dropListView();
|
||||
return;
|
||||
}
|
||||
|
||||
m_focusChain.append(FocusControl::getSubChain(rootObject));
|
||||
|
||||
std::sort(m_focusChain.begin(), m_focusChain.end(),
|
||||
direction == Direction::Forward ? FocusControl::isLess : FocusControl::isMore);
|
||||
|
||||
if (m_focusChain.empty()) {
|
||||
qWarning() << "Focus chain is empty!";
|
||||
resetRootObject();
|
||||
dropListView();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void FocusController::nextItem(Direction direction)
|
||||
{
|
||||
reload(direction);
|
||||
|
||||
if (m_lvfc && FocusControl::isListView(m_focusedItem)) {
|
||||
direction == Direction::Forward ? focusNextListViewItem() : focusPreviousListViewItem();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_focusChain.empty()) {
|
||||
qWarning() << "There are no items to navigate";
|
||||
setFocusOnDefaultItem();
|
||||
return;
|
||||
}
|
||||
|
||||
auto focusedItemIndex = m_focusChain.indexOf(m_focusedItem);
|
||||
|
||||
if (focusedItemIndex == -1) {
|
||||
focusedItemIndex = 0;
|
||||
} else if (focusedItemIndex == (m_focusChain.size() - 1)) {
|
||||
focusedItemIndex = 0;
|
||||
} else {
|
||||
focusedItemIndex++;
|
||||
}
|
||||
|
||||
const auto focusedItem = qobject_cast<QQuickItem *>(m_focusChain.at(focusedItemIndex));
|
||||
|
||||
if (focusedItem == nullptr) {
|
||||
qWarning() << "Failed to get item to focus on. Setting focus on default";
|
||||
setFocusOnDefaultItem();
|
||||
return;
|
||||
}
|
||||
|
||||
if (FocusControl::isListView(focusedItem)) {
|
||||
m_lvfc = new ListViewFocusController(focusedItem, this);
|
||||
m_focusedItem = focusedItem;
|
||||
if (direction == Direction::Forward) {
|
||||
m_lvfc->nextDelegate();
|
||||
focusNextListViewItem();
|
||||
} else {
|
||||
m_lvfc->previousDelegate();
|
||||
focusPreviousListViewItem();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
setFocusItem(focusedItem);
|
||||
}
|
||||
|
||||
void FocusController::focusNextListViewItem()
|
||||
{
|
||||
m_lvfc->reloadFocusChain();
|
||||
if (m_lvfc->isLastFocusItemInListView() || m_lvfc->isReturnNeeded()) {
|
||||
dropListView();
|
||||
nextItem(Direction::Forward);
|
||||
return;
|
||||
} else if (m_lvfc->isLastFocusItemInDelegate()) {
|
||||
m_lvfc->resetFocusChain();
|
||||
m_lvfc->nextDelegate();
|
||||
}
|
||||
|
||||
m_lvfc->focusNextItem();
|
||||
}
|
||||
|
||||
void FocusController::focusPreviousListViewItem()
|
||||
{
|
||||
m_lvfc->reloadFocusChain();
|
||||
if (m_lvfc->isFirstFocusItemInListView() || m_lvfc->isReturnNeeded()) {
|
||||
dropListView();
|
||||
nextItem(Direction::Backward);
|
||||
return;
|
||||
} else if (m_lvfc->isFirstFocusItemInDelegate()) {
|
||||
m_lvfc->resetFocusChain();
|
||||
m_lvfc->previousDelegate();
|
||||
}
|
||||
|
||||
m_lvfc->focusPreviousItem();
|
||||
}
|
||||
|
||||
void FocusController::dropListView()
|
||||
{
|
||||
if (m_lvfc) {
|
||||
delete m_lvfc;
|
||||
m_lvfc = nullptr;
|
||||
}
|
||||
}
|
||||
57
client/ui/controllers/focusController.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#ifndef FOCUSCONTROLLER_H
|
||||
#define FOCUSCONTROLLER_H
|
||||
|
||||
#include "ui/controllers/listViewFocusController.h"
|
||||
|
||||
#include <QQmlApplicationEngine>
|
||||
|
||||
/*!
|
||||
* \brief The FocusController class makes focus control more straightforward
|
||||
* \details Focus is handled only for visible and enabled items which have
|
||||
* `isFocused` property from top left to bottom right.
|
||||
* \note There are items handled differently (e.g. ListView)
|
||||
*/
|
||||
class FocusController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FocusController(QQmlApplicationEngine *engine, QObject *parent = nullptr);
|
||||
~FocusController() override = default;
|
||||
|
||||
Q_INVOKABLE void nextKeyTabItem();
|
||||
Q_INVOKABLE void previousKeyTabItem();
|
||||
Q_INVOKABLE void nextKeyUpItem();
|
||||
Q_INVOKABLE void nextKeyDownItem();
|
||||
Q_INVOKABLE void nextKeyLeftItem();
|
||||
Q_INVOKABLE void nextKeyRightItem();
|
||||
Q_INVOKABLE void setFocusItem(QQuickItem *item);
|
||||
Q_INVOKABLE void setFocusOnDefaultItem();
|
||||
Q_INVOKABLE void pushRootObject(QObject *object);
|
||||
Q_INVOKABLE void dropRootObject(QObject *object);
|
||||
Q_INVOKABLE void resetRootObject();
|
||||
|
||||
private:
|
||||
enum class Direction {
|
||||
Forward,
|
||||
Backward,
|
||||
};
|
||||
|
||||
void reload(Direction direction);
|
||||
void nextItem(Direction direction);
|
||||
void focusNextListViewItem();
|
||||
void focusPreviousListViewItem();
|
||||
void dropListView();
|
||||
|
||||
QSharedPointer<QQmlApplicationEngine> m_engine; // Pointer to engine to get root object
|
||||
QList<QObject *> m_focusChain; // List of current objects to be focused
|
||||
QQuickItem *m_focusedItem; // Pointer to the active focus item
|
||||
QStack<QObject *> m_rootObjects;
|
||||
QSharedPointer<QQuickItem> m_defaultFocusItem;
|
||||
|
||||
ListViewFocusController *m_lvfc; // ListView focus manager
|
||||
|
||||
signals:
|
||||
void focusedItemChanged();
|
||||
};
|
||||
|
||||
#endif // FOCUSCONTROLLER_H
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "core/errorstrings.h"
|
||||
#include "core/serialization/serialization.h"
|
||||
#include "systemController.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
@@ -76,17 +77,18 @@ ImportController::ImportController(const QSharedPointer<ServersModel> &serversMo
|
||||
|
||||
bool ImportController::extractConfigFromFile(const QString &fileName)
|
||||
{
|
||||
QFile file(fileName);
|
||||
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
QString data = file.readAll();
|
||||
|
||||
m_configFileName = QFileInfo(file.fileName()).fileName();
|
||||
return extractConfigFromData(data);
|
||||
QString data;
|
||||
if (!SystemController::readFile(fileName, data)) {
|
||||
emit importErrorOccurred(ErrorCode::ImportOpenConfigError, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
emit importErrorOccurred(ErrorCode::ImportOpenConfigError, false);
|
||||
return false;
|
||||
m_configFileName = QFileInfo(QFile(fileName).fileName()).fileName();
|
||||
#ifdef Q_OS_ANDROID
|
||||
if (m_configFileName.isEmpty()) {
|
||||
m_configFileName = AndroidController::instance()->getFileName(fileName);
|
||||
}
|
||||
#endif
|
||||
return extractConfigFromData(data);
|
||||
}
|
||||
|
||||
bool ImportController::extractConfigFromData(QString data)
|
||||
|
||||
@@ -848,7 +848,6 @@ bool InstallController::updateServiceFromApi(const int serverIndex, const QStrin
|
||||
|
||||
newServerConfig.insert(configKey::apiConfig, newApiConfig);
|
||||
newServerConfig.insert(configKey::authData, authData);
|
||||
newServerConfig.insert(config_key::crc, serverConfig.value(config_key::crc));
|
||||
m_serversModel->editServer(newServerConfig, serverIndex);
|
||||
|
||||
if (reloadServiceConfig) {
|
||||
|
||||
309
client/ui/controllers/listViewFocusController.cpp
Normal file
@@ -0,0 +1,309 @@
|
||||
#include "listViewFocusController.h"
|
||||
#include "utils/qmlUtils.h"
|
||||
|
||||
#include <QQuickWindow>
|
||||
|
||||
ListViewFocusController::ListViewFocusController(QQuickItem *listView, QObject *parent)
|
||||
: QObject { parent },
|
||||
m_listView { listView },
|
||||
m_focusChain {},
|
||||
m_currentSection { Section::Default },
|
||||
m_header { nullptr },
|
||||
m_footer { nullptr },
|
||||
m_focusedItem { nullptr },
|
||||
m_focusedItemIndex { -1 },
|
||||
m_delegateIndex { 0 },
|
||||
m_isReturnNeeded { false },
|
||||
m_currentSectionString { "Default", "Header", "Delegate", "Footer" }
|
||||
{
|
||||
QVariant headerItemProperty = m_listView->property("headerItem");
|
||||
m_header = headerItemProperty.canConvert<QQuickItem *>() ? headerItemProperty.value<QQuickItem *>() : nullptr;
|
||||
|
||||
QVariant footerItemProperty = m_listView->property("footerItem");
|
||||
m_footer = footerItemProperty.canConvert<QQuickItem *>() ? footerItemProperty.value<QQuickItem *>() : nullptr;
|
||||
}
|
||||
|
||||
ListViewFocusController::~ListViewFocusController()
|
||||
{
|
||||
}
|
||||
|
||||
void ListViewFocusController::viewAtCurrentIndex() const
|
||||
{
|
||||
switch (m_currentSection) {
|
||||
case Section::Default: [[fallthrough]];
|
||||
case Section::Header: {
|
||||
QMetaObject::invokeMethod(m_listView, "positionViewAtBeginning");
|
||||
break;
|
||||
}
|
||||
case Section::Delegate: {
|
||||
QMetaObject::invokeMethod(m_listView, "positionViewAtIndex", Q_ARG(int, m_delegateIndex), // Index
|
||||
Q_ARG(int, 2)); // PositionMode (0 = Visible)
|
||||
break;
|
||||
}
|
||||
case Section::Footer: {
|
||||
QMetaObject::invokeMethod(m_listView, "positionViewAtEnd");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ListViewFocusController::size() const
|
||||
{
|
||||
return m_listView->property("count").toInt();
|
||||
}
|
||||
|
||||
int ListViewFocusController::currentIndex() const
|
||||
{
|
||||
return m_delegateIndex;
|
||||
}
|
||||
|
||||
void ListViewFocusController::setDelegateIndex(int index)
|
||||
{
|
||||
m_delegateIndex = index;
|
||||
m_listView->setProperty("currentIndex", index);
|
||||
}
|
||||
|
||||
void ListViewFocusController::nextDelegate()
|
||||
{
|
||||
switch (m_currentSection) {
|
||||
case Section::Default: {
|
||||
if (hasHeader()) {
|
||||
m_currentSection = Section::Header;
|
||||
viewAtCurrentIndex();
|
||||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
}
|
||||
case Section::Header: {
|
||||
if (size() > 0) {
|
||||
m_currentSection = Section::Delegate;
|
||||
viewAtCurrentIndex();
|
||||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
}
|
||||
case Section::Delegate:
|
||||
if (m_delegateIndex < (size() - 1)) {
|
||||
setDelegateIndex(m_delegateIndex + 1);
|
||||
viewAtCurrentIndex();
|
||||
break;
|
||||
} else if (hasFooter()) {
|
||||
m_currentSection = Section::Footer;
|
||||
viewAtCurrentIndex();
|
||||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
case Section::Footer: {
|
||||
m_isReturnNeeded = true;
|
||||
m_currentSection = Section::Default;
|
||||
viewAtCurrentIndex();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
qCritical() << "Current section is invalid!";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ListViewFocusController::previousDelegate()
|
||||
{
|
||||
switch (m_currentSection) {
|
||||
case Section::Default: {
|
||||
if (hasFooter()) {
|
||||
m_currentSection = Section::Footer;
|
||||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
}
|
||||
case Section::Footer: {
|
||||
if (size() > 0) {
|
||||
m_currentSection = Section::Delegate;
|
||||
setDelegateIndex(size() - 1);
|
||||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
}
|
||||
case Section::Delegate: {
|
||||
if (m_delegateIndex > 0) {
|
||||
setDelegateIndex(m_delegateIndex - 1);
|
||||
break;
|
||||
} else if (hasHeader()) {
|
||||
m_currentSection = Section::Header;
|
||||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
}
|
||||
case Section::Header: {
|
||||
m_isReturnNeeded = true;
|
||||
m_currentSection = Section::Default;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
qCritical() << "Current section is invalid!";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ListViewFocusController::decrementIndex()
|
||||
{
|
||||
m_delegateIndex--;
|
||||
}
|
||||
|
||||
QQuickItem *ListViewFocusController::itemAtIndex(const int index) const
|
||||
{
|
||||
QQuickItem *item { nullptr };
|
||||
|
||||
QMetaObject::invokeMethod(m_listView, "itemAtIndex", Q_RETURN_ARG(QQuickItem *, item), Q_ARG(int, index));
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
QQuickItem *ListViewFocusController::currentDelegate() const
|
||||
{
|
||||
QQuickItem *result { nullptr };
|
||||
|
||||
switch (m_currentSection) {
|
||||
case Section::Default: {
|
||||
qWarning() << "No elements...";
|
||||
break;
|
||||
}
|
||||
case Section::Header: {
|
||||
result = m_header;
|
||||
break;
|
||||
}
|
||||
case Section::Delegate: {
|
||||
result = itemAtIndex(m_delegateIndex);
|
||||
break;
|
||||
}
|
||||
case Section::Footer: {
|
||||
result = m_footer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QQuickItem *ListViewFocusController::focusedItem() const
|
||||
{
|
||||
return m_focusedItem;
|
||||
}
|
||||
|
||||
void ListViewFocusController::focusNextItem()
|
||||
{
|
||||
if (m_isReturnNeeded) {
|
||||
return;
|
||||
}
|
||||
|
||||
reloadFocusChain();
|
||||
|
||||
if (m_focusChain.empty()) {
|
||||
qWarning() << "No elements found in the delegate. Going to next delegate...";
|
||||
nextDelegate();
|
||||
focusNextItem();
|
||||
return;
|
||||
}
|
||||
m_focusedItemIndex++;
|
||||
m_focusedItem = qobject_cast<QQuickItem *>(m_focusChain.at(m_focusedItemIndex));
|
||||
m_focusedItem->forceActiveFocus(Qt::TabFocusReason);
|
||||
}
|
||||
|
||||
void ListViewFocusController::focusPreviousItem()
|
||||
{
|
||||
if (m_isReturnNeeded) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_focusChain.empty()) {
|
||||
qInfo() << "Empty focusChain with current delegate: " << currentDelegate() << "Scanning for elements...";
|
||||
reloadFocusChain();
|
||||
}
|
||||
if (m_focusChain.empty()) {
|
||||
qWarning() << "No elements found in the delegate. Going to next delegate...";
|
||||
previousDelegate();
|
||||
focusPreviousItem();
|
||||
return;
|
||||
}
|
||||
if (m_focusedItemIndex == -1) {
|
||||
m_focusedItemIndex = m_focusChain.size();
|
||||
}
|
||||
m_focusedItemIndex--;
|
||||
m_focusedItem = qobject_cast<QQuickItem *>(m_focusChain.at(m_focusedItemIndex));
|
||||
m_focusedItem->forceActiveFocus(Qt::TabFocusReason);
|
||||
}
|
||||
|
||||
void ListViewFocusController::resetFocusChain()
|
||||
{
|
||||
m_focusChain.clear();
|
||||
m_focusedItem = nullptr;
|
||||
m_focusedItemIndex = -1;
|
||||
}
|
||||
|
||||
void ListViewFocusController::reloadFocusChain()
|
||||
{
|
||||
m_focusChain = FocusControl::getItemsChain(currentDelegate());
|
||||
}
|
||||
|
||||
bool ListViewFocusController::isFirstFocusItemInDelegate() const
|
||||
{
|
||||
return m_focusedItem && (m_focusedItem == m_focusChain.first());
|
||||
}
|
||||
|
||||
bool ListViewFocusController::isLastFocusItemInDelegate() const
|
||||
{
|
||||
return m_focusedItem && (m_focusedItem == m_focusChain.last());
|
||||
}
|
||||
|
||||
bool ListViewFocusController::hasHeader() const
|
||||
{
|
||||
return m_header && !FocusControl::getItemsChain(m_header).isEmpty();
|
||||
}
|
||||
|
||||
bool ListViewFocusController::hasFooter() const
|
||||
{
|
||||
return m_footer && !FocusControl::getItemsChain(m_footer).isEmpty();
|
||||
}
|
||||
|
||||
bool ListViewFocusController::isFirstFocusItemInListView() const
|
||||
{
|
||||
switch (m_currentSection) {
|
||||
case Section::Footer: {
|
||||
return isFirstFocusItemInDelegate() && !hasHeader() && (size() == 0);
|
||||
}
|
||||
case Section::Delegate: {
|
||||
return isFirstFocusItemInDelegate() && (m_delegateIndex == 0) && !hasHeader();
|
||||
}
|
||||
case Section::Header: {
|
||||
isFirstFocusItemInDelegate();
|
||||
}
|
||||
case Section::Default: {
|
||||
return true;
|
||||
}
|
||||
default: qWarning() << "Wrong section"; return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool ListViewFocusController::isLastFocusItemInListView() const
|
||||
{
|
||||
switch (m_currentSection) {
|
||||
case Section::Default: {
|
||||
return !hasHeader() && (size() == 0) && !hasFooter();
|
||||
}
|
||||
case Section::Header: {
|
||||
return isLastFocusItemInDelegate() && (size() == 0) && !hasFooter();
|
||||
}
|
||||
case Section::Delegate: {
|
||||
return isLastFocusItemInDelegate() && (m_delegateIndex == size() - 1) && !hasFooter();
|
||||
}
|
||||
case Section::Footer: {
|
||||
return isLastFocusItemInDelegate();
|
||||
}
|
||||
default: qWarning() << "Wrong section"; return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool ListViewFocusController::isReturnNeeded() const
|
||||
{
|
||||
return m_isReturnNeeded;
|
||||
}
|
||||
70
client/ui/controllers/listViewFocusController.h
Normal file
@@ -0,0 +1,70 @@
|
||||
#ifndef LISTVIEWFOCUSCONTROLLER_H
|
||||
#define LISTVIEWFOCUSCONTROLLER_H
|
||||
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
#include <QQuickItem>
|
||||
#include <QSharedPointer>
|
||||
#include <QStack>
|
||||
|
||||
/*!
|
||||
* \brief The ListViewFocusController class manages the focus of elements in ListView
|
||||
* \details This class object moving focus to ListView's controls since ListView stores
|
||||
* it's data implicitly and it could be got one by one.
|
||||
*
|
||||
* This class was made to store as less as possible data getting it from QML
|
||||
* when it's needed.
|
||||
*/
|
||||
class ListViewFocusController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ListViewFocusController(QQuickItem *listView, QObject *parent = nullptr);
|
||||
~ListViewFocusController();
|
||||
|
||||
void nextDelegate();
|
||||
void previousDelegate();
|
||||
void decrementIndex();
|
||||
void focusNextItem();
|
||||
void focusPreviousItem();
|
||||
void resetFocusChain();
|
||||
void reloadFocusChain();
|
||||
bool isFirstFocusItemInListView() const;
|
||||
bool isFirstFocusItemInDelegate() const;
|
||||
bool isLastFocusItemInListView() const;
|
||||
bool isLastFocusItemInDelegate() const;
|
||||
bool isReturnNeeded() const;
|
||||
|
||||
private:
|
||||
enum class Section {
|
||||
Default,
|
||||
Header,
|
||||
Delegate,
|
||||
Footer,
|
||||
};
|
||||
|
||||
int size() const;
|
||||
int currentIndex() const;
|
||||
void setDelegateIndex(int index);
|
||||
void viewAtCurrentIndex() const;
|
||||
QQuickItem *itemAtIndex(const int index) const;
|
||||
QQuickItem *currentDelegate() const;
|
||||
QQuickItem *focusedItem() const;
|
||||
|
||||
bool hasHeader() const;
|
||||
bool hasFooter() const;
|
||||
|
||||
QQuickItem *m_listView;
|
||||
QList<QObject *> m_focusChain;
|
||||
Section m_currentSection;
|
||||
QQuickItem *m_header;
|
||||
QQuickItem *m_footer;
|
||||
QQuickItem *m_focusedItem; // Pointer to focused item on Delegate
|
||||
qsizetype m_focusedItemIndex;
|
||||
qsizetype m_delegateIndex;
|
||||
bool m_isReturnNeeded;
|
||||
|
||||
QList<QString> m_currentSectionString;
|
||||
};
|
||||
|
||||
#endif // LISTVIEWFOCUSCONTROLLER_H
|
||||
@@ -24,7 +24,7 @@ PageController::PageController(const QSharedPointer<ServersModel> &serversModel,
|
||||
AndroidController::instance()->setNavigationBarColor(initialPageNavigationBarColor);
|
||||
#endif
|
||||
|
||||
#if defined Q_OS_MACX and !defined MACOS_NE
|
||||
#if defined Q_OS_MACX
|
||||
connect(this, &PageController::raiseMainWindow, []() { setDockIconVisible(true); });
|
||||
connect(this, &PageController::hideMainWindow, []() { setDockIconVisible(false); });
|
||||
#endif
|
||||
@@ -81,7 +81,7 @@ void PageController::keyPressEvent(Qt::Key key)
|
||||
case Qt::Key_Escape: {
|
||||
if (m_drawerDepth) {
|
||||
emit closeTopDrawer();
|
||||
setDrawerDepth(getDrawerDepth() - 1);
|
||||
decrementDrawerDepth();
|
||||
} else {
|
||||
emit escapePressed();
|
||||
}
|
||||
@@ -114,7 +114,7 @@ void PageController::showOnStartup()
|
||||
} else {
|
||||
#if defined(Q_OS_WIN) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
emit hideMainWindow();
|
||||
#elif defined Q_OS_MACX and !defined MACOS_NE
|
||||
#elif defined Q_OS_MACX
|
||||
setDockIconVisible(false);
|
||||
#endif
|
||||
}
|
||||
@@ -142,11 +142,25 @@ void PageController::setDrawerDepth(const int depth)
|
||||
}
|
||||
}
|
||||
|
||||
int PageController::getDrawerDepth()
|
||||
int PageController::getDrawerDepth() const
|
||||
{
|
||||
return m_drawerDepth;
|
||||
}
|
||||
|
||||
int PageController::incrementDrawerDepth()
|
||||
{
|
||||
return ++m_drawerDepth;
|
||||
}
|
||||
|
||||
int PageController::decrementDrawerDepth()
|
||||
{
|
||||
if (m_drawerDepth == 0) {
|
||||
return m_drawerDepth;
|
||||
} else {
|
||||
return --m_drawerDepth;
|
||||
}
|
||||
}
|
||||
|
||||
void PageController::onShowErrorMessage(ErrorCode errorCode)
|
||||
{
|
||||
const auto fullErrorMessage = errorString(errorCode);
|
||||
|
||||
@@ -100,7 +100,9 @@ public slots:
|
||||
void closeApplication();
|
||||
|
||||
void setDrawerDepth(const int depth);
|
||||
int getDrawerDepth();
|
||||
int getDrawerDepth() const;
|
||||
int incrementDrawerDepth();
|
||||
int decrementDrawerDepth();
|
||||
|
||||
private slots:
|
||||
void onShowErrorMessage(amnezia::ErrorCode errorCode);
|
||||
@@ -135,9 +137,6 @@ signals:
|
||||
void escapePressed();
|
||||
void closeTopDrawer();
|
||||
|
||||
void forceTabBarActiveFocus();
|
||||
void forceStackActiveFocus();
|
||||
|
||||
private:
|
||||
QSharedPointer<ServersModel> m_serversModel;
|
||||
|
||||
|
||||
@@ -131,12 +131,8 @@ void SettingsController::backupAppConfig(const QString &fileName)
|
||||
|
||||
void SettingsController::restoreAppConfig(const QString &fileName)
|
||||
{
|
||||
QFile file(fileName);
|
||||
|
||||
file.open(QIODevice::ReadOnly);
|
||||
|
||||
QByteArray data = file.readAll();
|
||||
|
||||
QByteArray data;
|
||||
SystemController::readFile(fileName, data);
|
||||
restoreAppConfigFromData(data);
|
||||
}
|
||||
|
||||
|
||||
@@ -82,14 +82,12 @@ void SitesController::removeSite(int index)
|
||||
|
||||
void SitesController::importSites(const QString &fileName, bool replaceExisting)
|
||||
{
|
||||
QFile file(fileName);
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
QByteArray jsonData;
|
||||
if (!SystemController::readFile(fileName, jsonData)) {
|
||||
emit errorOccurred(tr("Can't open file: %1").arg(fileName));
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray jsonData = file.readAll();
|
||||
QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonData);
|
||||
if (jsonDocument.isNull()) {
|
||||
emit errorOccurred(tr("Failed to parse JSON data from file: %1").arg(fileName));
|
||||
|
||||
@@ -24,7 +24,7 @@ SystemController::SystemController(const std::shared_ptr<Settings> &settings, QO
|
||||
{
|
||||
}
|
||||
|
||||
void SystemController::saveFile(QString fileName, const QString &data)
|
||||
void SystemController::saveFile(const QString &fileName, const QString &data)
|
||||
{
|
||||
#if defined Q_OS_ANDROID
|
||||
AndroidController::instance()->saveFile(fileName, data);
|
||||
@@ -62,6 +62,31 @@ void SystemController::saveFile(QString fileName, const QString &data)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SystemController::readFile(const QString &fileName, QByteArray &data)
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
int fd = AndroidController::instance()->getFd(fileName);
|
||||
if (fd == -1) return false;
|
||||
QFile file;
|
||||
if(!file.open(fd, QIODevice::ReadOnly)) return false;
|
||||
data = file.readAll();
|
||||
AndroidController::instance()->closeFd();
|
||||
#else
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::ReadOnly)) return false;
|
||||
data = file.readAll();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SystemController::readFile(const QString &fileName, QString &data)
|
||||
{
|
||||
QByteArray byteArray;
|
||||
if(!readFile(fileName, byteArray)) return false;
|
||||
data = byteArray;
|
||||
return true;
|
||||
}
|
||||
|
||||
QString SystemController::getFileName(const QString &acceptLabel, const QString &nameFilter,
|
||||
const QString &selectedFile, const bool isSaveMode, const QString &defaultSuffix)
|
||||
{
|
||||
@@ -134,3 +159,10 @@ bool SystemController::isAuthenticated()
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SystemController::sendTouch(float x, float y)
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
AndroidController::instance()->sendTouch(x, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -11,7 +11,9 @@ class SystemController : public QObject
|
||||
public:
|
||||
explicit SystemController(const std::shared_ptr<Settings> &setting, QObject *parent = nullptr);
|
||||
|
||||
static void saveFile(QString fileName, const QString &data);
|
||||
static void saveFile(const QString &fileName, const QString &data);
|
||||
static bool readFile(const QString &fileName, QByteArray &data);
|
||||
static bool readFile(const QString &fileName, QString &data);
|
||||
|
||||
public slots:
|
||||
QString getFileName(const QString &acceptLabel, const QString &nameFilter, const QString &selectedFile = "",
|
||||
@@ -20,6 +22,8 @@ public slots:
|
||||
void setQmlRoot(QObject *qmlRoot);
|
||||
|
||||
bool isAuthenticated();
|
||||
void sendTouch(float x, float y);
|
||||
|
||||
signals:
|
||||
void fileDialogClosed(const bool isAccepted);
|
||||
|
||||
|
||||
@@ -27,6 +27,9 @@ namespace
|
||||
constexpr char storeEndpoint[] = "store_endpoint";
|
||||
|
||||
constexpr char isAvailable[] = "is_available";
|
||||
|
||||
constexpr char subscription[] = "subscription";
|
||||
constexpr char endDate[] = "end_date";
|
||||
}
|
||||
|
||||
namespace serviceType
|
||||
@@ -51,23 +54,23 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= static_cast<int>(rowCount()))
|
||||
return QVariant();
|
||||
|
||||
QJsonObject service = m_services.at(index.row()).toObject();
|
||||
QJsonObject serviceInfo = service.value(configKey::serviceInfo).toObject();
|
||||
auto serviceType = service.value(configKey::serviceType).toString();
|
||||
auto apiServiceData = m_services.at(index.row());
|
||||
auto serviceType = apiServiceData.type;
|
||||
auto isServiceAvailable = apiServiceData.isServiceAvailable;
|
||||
|
||||
switch (role) {
|
||||
case NameRole: {
|
||||
return serviceInfo.value(configKey::name).toString();
|
||||
return apiServiceData.serviceInfo.name;
|
||||
}
|
||||
case CardDescriptionRole: {
|
||||
auto speed = serviceInfo.value(configKey::speed).toString();
|
||||
auto speed = apiServiceData.serviceInfo.speed;
|
||||
if (serviceType == serviceType::amneziaPremium) {
|
||||
return tr("Classic VPN for comfortable work, downloading large files and watching videos. "
|
||||
"Works for any sites. Speed up to %1 MBit/s")
|
||||
.arg(speed);
|
||||
} else if (serviceType == serviceType::amneziaFree){
|
||||
QString description = tr("VPN to access blocked sites in regions with high levels of Internet censorship. ");
|
||||
if (service.value(configKey::isAvailable).isBool() && !service.value(configKey::isAvailable).toBool()) {
|
||||
if (isServiceAvailable) {
|
||||
description += tr("<p><a style=\"color: #EB5757;\">Not available in your region. If you have VPN enabled, disable it, return to the previous screen, and try again.</a>");
|
||||
}
|
||||
return description;
|
||||
@@ -83,25 +86,24 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
|
||||
}
|
||||
case IsServiceAvailableRole: {
|
||||
if (serviceType == serviceType::amneziaFree) {
|
||||
if (service.value(configKey::isAvailable).isBool() && !service.value(configKey::isAvailable).toBool()) {
|
||||
if (isServiceAvailable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case SpeedRole: {
|
||||
auto speed = serviceInfo.value(configKey::speed).toString();
|
||||
return tr("%1 MBit/s").arg(speed);
|
||||
return tr("%1 MBit/s").arg(apiServiceData.serviceInfo.speed);
|
||||
}
|
||||
case WorkPeriodRole: {
|
||||
auto timelimit = serviceInfo.value(configKey::timelimit).toString();
|
||||
if (timelimit == "0") {
|
||||
case TimeLimitRole: {
|
||||
auto timeLimit = apiServiceData.serviceInfo.timeLimit;
|
||||
if (timeLimit == "0") {
|
||||
return "";
|
||||
}
|
||||
return tr("%1 days").arg(timelimit);
|
||||
return tr("%1 days").arg(timeLimit);
|
||||
}
|
||||
case RegionRole: {
|
||||
return serviceInfo.value(configKey::region).toString();
|
||||
return apiServiceData.serviceInfo.region;
|
||||
}
|
||||
case FeaturesRole: {
|
||||
if (serviceType == serviceType::amneziaPremium) {
|
||||
@@ -113,12 +115,15 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
|
||||
}
|
||||
}
|
||||
case PriceRole: {
|
||||
auto price = serviceInfo.value(configKey::price).toString();
|
||||
auto price = apiServiceData.serviceInfo.price;
|
||||
if (price == "free") {
|
||||
return tr("Free");
|
||||
}
|
||||
return tr("%1 $/month").arg(price);
|
||||
}
|
||||
case EndDateRole: {
|
||||
return QDateTime::fromString(apiServiceData.subscription.endDate, Qt::ISODate).toLocalTime().toString("d MMM yyyy");
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
@@ -128,15 +133,18 @@ void ApiServicesModel::updateModel(const QJsonObject &data)
|
||||
{
|
||||
beginResetModel();
|
||||
|
||||
m_countryCode = data.value(configKey::userCountryCode).toString();
|
||||
m_services = data.value(configKey::services).toArray();
|
||||
if (m_services.isEmpty()) {
|
||||
QJsonObject service;
|
||||
service.insert(configKey::serviceInfo, data.value(configKey::serviceInfo));
|
||||
service.insert(configKey::serviceType, data.value(configKey::serviceType));
|
||||
m_services.clear();
|
||||
|
||||
m_services.push_back(service);
|
||||
m_countryCode = data.value(configKey::userCountryCode).toString();
|
||||
auto services = data.value(configKey::services).toArray();
|
||||
|
||||
if (services.isEmpty()) {
|
||||
m_services.push_back(getApiServicesData(data));
|
||||
m_selectedServiceIndex = 0;
|
||||
} else {
|
||||
for (const auto &service : services) {
|
||||
m_services.push_back(getApiServicesData(service.toObject()));
|
||||
}
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
@@ -149,32 +157,32 @@ void ApiServicesModel::setServiceIndex(const int index)
|
||||
|
||||
QJsonObject ApiServicesModel::getSelectedServiceInfo()
|
||||
{
|
||||
QJsonObject service = m_services.at(m_selectedServiceIndex).toObject();
|
||||
return service.value(configKey::serviceInfo).toObject();
|
||||
auto service = m_services.at(m_selectedServiceIndex);
|
||||
return service.serviceInfo.object;
|
||||
}
|
||||
|
||||
QString ApiServicesModel::getSelectedServiceType()
|
||||
{
|
||||
QJsonObject service = m_services.at(m_selectedServiceIndex).toObject();
|
||||
return service.value(configKey::serviceType).toString();
|
||||
auto service = m_services.at(m_selectedServiceIndex);
|
||||
return service.type;
|
||||
}
|
||||
|
||||
QString ApiServicesModel::getSelectedServiceProtocol()
|
||||
{
|
||||
QJsonObject service = m_services.at(m_selectedServiceIndex).toObject();
|
||||
return service.value(configKey::serviceProtocol).toString();
|
||||
auto service = m_services.at(m_selectedServiceIndex);
|
||||
return service.protocol;
|
||||
}
|
||||
|
||||
QString ApiServicesModel::getSelectedServiceName()
|
||||
{
|
||||
auto modelIndex = index(m_selectedServiceIndex, 0);
|
||||
return data(modelIndex, ApiServicesModel::Roles::NameRole).toString();
|
||||
auto service = m_services.at(m_selectedServiceIndex);
|
||||
return service.serviceInfo.name;
|
||||
}
|
||||
|
||||
QJsonArray ApiServicesModel::getSelectedServiceCountries()
|
||||
{
|
||||
QJsonObject service = m_services.at(m_selectedServiceIndex).toObject();
|
||||
return service.value(configKey::availableCountries).toArray();
|
||||
auto service = m_services.at(m_selectedServiceIndex);
|
||||
return service.availableCountries;
|
||||
}
|
||||
|
||||
QString ApiServicesModel::getCountryCode()
|
||||
@@ -184,8 +192,8 @@ QString ApiServicesModel::getCountryCode()
|
||||
|
||||
QString ApiServicesModel::getStoreEndpoint()
|
||||
{
|
||||
QJsonObject service = m_services.at(m_selectedServiceIndex).toObject();
|
||||
return service.value(configKey::storeEndpoint).toString();
|
||||
auto service = m_services.at(m_selectedServiceIndex);
|
||||
return service.storeEndpoint;
|
||||
}
|
||||
|
||||
QVariant ApiServicesModel::getSelectedServiceData(const QString roleString)
|
||||
@@ -209,10 +217,46 @@ QHash<int, QByteArray> ApiServicesModel::roleNames() const
|
||||
roles[ServiceDescriptionRole] = "serviceDescription";
|
||||
roles[IsServiceAvailableRole] = "isServiceAvailable";
|
||||
roles[SpeedRole] = "speed";
|
||||
roles[WorkPeriodRole] = "workPeriod";
|
||||
roles[TimeLimitRole] = "timeLimit";
|
||||
roles[RegionRole] = "region";
|
||||
roles[FeaturesRole] = "features";
|
||||
roles[PriceRole] = "price";
|
||||
roles[EndDateRole] = "endDate";
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
ApiServicesModel::ApiServicesData ApiServicesModel::getApiServicesData(const QJsonObject &data)
|
||||
{
|
||||
auto serviceInfo = data.value(configKey::serviceInfo).toObject();
|
||||
auto serviceType = data.value(configKey::serviceType).toString();
|
||||
auto serviceProtocol = data.value(configKey::serviceProtocol).toString();
|
||||
auto availableCountries = data.value(configKey::availableCountries).toArray();
|
||||
|
||||
auto subscriptionObject = data.value(configKey::subscription).toObject();
|
||||
|
||||
ApiServicesData serviceData;
|
||||
serviceData.serviceInfo.name = serviceInfo.value(configKey::name).toString();
|
||||
serviceData.serviceInfo.price = serviceInfo.value(configKey::price).toString();
|
||||
serviceData.serviceInfo.region = serviceInfo.value(configKey::region).toString();
|
||||
serviceData.serviceInfo.speed = serviceInfo.value(configKey::speed).toString();
|
||||
serviceData.serviceInfo.timeLimit = serviceInfo.value(configKey::timelimit).toString();
|
||||
|
||||
serviceData.type = serviceType;
|
||||
serviceData.protocol = serviceProtocol;
|
||||
|
||||
serviceData.storeEndpoint = serviceInfo.value(configKey::storeEndpoint).toString();
|
||||
|
||||
if (serviceInfo.value(configKey::isAvailable).isBool()) {
|
||||
serviceData.isServiceAvailable = data.value(configKey::isAvailable).toBool();
|
||||
} else {
|
||||
serviceData.isServiceAvailable = true;
|
||||
}
|
||||
|
||||
serviceData.serviceInfo.object = serviceInfo;
|
||||
serviceData.availableCountries = availableCountries;
|
||||
|
||||
serviceData.subscription.endDate = subscriptionObject.value(configKey::endDate).toString();
|
||||
|
||||
return serviceData;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
class ApiServicesModel : public QAbstractListModel
|
||||
{
|
||||
@@ -15,10 +16,11 @@ public:
|
||||
ServiceDescriptionRole,
|
||||
IsServiceAvailableRole,
|
||||
SpeedRole,
|
||||
WorkPeriodRole,
|
||||
TimeLimitRole,
|
||||
RegionRole,
|
||||
FeaturesRole,
|
||||
PriceRole
|
||||
PriceRole,
|
||||
EndDateRole
|
||||
};
|
||||
|
||||
explicit ApiServicesModel(QObject *parent = nullptr);
|
||||
@@ -48,8 +50,40 @@ protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
private:
|
||||
struct ServiceInfo
|
||||
{
|
||||
QString name;
|
||||
QString speed;
|
||||
QString timeLimit;
|
||||
QString region;
|
||||
QString price;
|
||||
|
||||
QJsonObject object;
|
||||
};
|
||||
|
||||
struct Subscription
|
||||
{
|
||||
QString endDate;
|
||||
};
|
||||
|
||||
struct ApiServicesData
|
||||
{
|
||||
bool isServiceAvailable;
|
||||
|
||||
QString type;
|
||||
QString protocol;
|
||||
QString storeEndpoint;
|
||||
|
||||
ServiceInfo serviceInfo;
|
||||
Subscription subscription;
|
||||
|
||||
QJsonArray availableCountries;
|
||||
};
|
||||
|
||||
ApiServicesData getApiServicesData(const QJsonObject &data);
|
||||
|
||||
QString m_countryCode;
|
||||
QJsonArray m_services;
|
||||
QVector<ApiServicesData> m_services;
|
||||
|
||||
int m_selectedServiceIndex;
|
||||
};
|
||||
|
||||
@@ -106,6 +106,8 @@ ErrorCode ClientManagementModel::updateModel(const DockerContainer container, co
|
||||
error = getOpenVpnClients(container, credentials, serverController, count);
|
||||
} else if (container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
|
||||
error = getWireGuardClients(container, credentials, serverController, count);
|
||||
} else if (container == DockerContainer::Xray) {
|
||||
error = getXrayClients(container, credentials, serverController, count);
|
||||
}
|
||||
if (error != ErrorCode::NoError) {
|
||||
endResetModel();
|
||||
@@ -239,6 +241,68 @@ ErrorCode ClientManagementModel::getWireGuardClients(const DockerContainer conta
|
||||
}
|
||||
return error;
|
||||
}
|
||||
ErrorCode ClientManagementModel::getXrayClients(const DockerContainer container, const ServerCredentials& credentials,
|
||||
const QSharedPointer<ServerController> &serverController, int &count)
|
||||
{
|
||||
ErrorCode error = ErrorCode::NoError;
|
||||
|
||||
const QString serverConfigPath = amnezia::protocols::xray::serverConfigPath;
|
||||
const QString configString = serverController->getTextFileFromContainer(container, credentials, serverConfigPath, error);
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to get the xray server config file from the server";
|
||||
return error;
|
||||
}
|
||||
|
||||
QJsonDocument serverConfig = QJsonDocument::fromJson(configString.toUtf8());
|
||||
if (serverConfig.isNull()) {
|
||||
logger.error() << "Failed to parse xray server config JSON";
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
if (!serverConfig.object().contains("inbounds") || serverConfig.object()["inbounds"].toArray().isEmpty()) {
|
||||
logger.error() << "Invalid xray server config structure";
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
const QJsonObject inbound = serverConfig.object()["inbounds"].toArray()[0].toObject();
|
||||
if (!inbound.contains("settings")) {
|
||||
logger.error() << "Missing settings in xray inbound config";
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
const QJsonObject settings = inbound["settings"].toObject();
|
||||
if (!settings.contains("clients")) {
|
||||
logger.error() << "Missing clients in xray settings config";
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
const QJsonArray clients = settings["clients"].toArray();
|
||||
for (const auto &clientValue : clients) {
|
||||
const QJsonObject clientObj = clientValue.toObject();
|
||||
if (!clientObj.contains("id")) {
|
||||
logger.error() << "Missing id in xray client config";
|
||||
continue;
|
||||
}
|
||||
QString clientId = clientObj["id"].toString();
|
||||
|
||||
QString xrayDefaultUuid = serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::xray::uuidPath, error);
|
||||
xrayDefaultUuid.replace("\n", "");
|
||||
|
||||
if (!isClientExists(clientId) && clientId != xrayDefaultUuid) {
|
||||
QJsonObject client;
|
||||
client[configKey::clientId] = clientId;
|
||||
|
||||
QJsonObject userData;
|
||||
userData[configKey::clientName] = QString("Client %1").arg(count);
|
||||
client[configKey::userData] = userData;
|
||||
|
||||
m_clientsTable.push_back(client);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
ErrorCode ClientManagementModel::wgShow(const DockerContainer container, const ServerCredentials &credentials,
|
||||
const QSharedPointer<ServerController> &serverController, std::vector<WgShowData> &data)
|
||||
@@ -326,17 +390,67 @@ ErrorCode ClientManagementModel::appendClient(const DockerContainer container, c
|
||||
const QSharedPointer<ServerController> &serverController)
|
||||
{
|
||||
Proto protocol;
|
||||
if (container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||
protocol = Proto::OpenVpn;
|
||||
} else if (container == DockerContainer::OpenVpn || container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
|
||||
protocol = ContainerProps::defaultProtocol(container);
|
||||
} else {
|
||||
return ErrorCode::NoError;
|
||||
switch (container) {
|
||||
case DockerContainer::ShadowSocks:
|
||||
case DockerContainer::Cloak:
|
||||
protocol = Proto::OpenVpn;
|
||||
break;
|
||||
case DockerContainer::OpenVpn:
|
||||
case DockerContainer::WireGuard:
|
||||
case DockerContainer::Awg:
|
||||
case DockerContainer::Xray:
|
||||
protocol = ContainerProps::defaultProtocol(container);
|
||||
break;
|
||||
default:
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
auto protocolConfig = ContainerProps::getProtocolConfigFromContainer(protocol, containerConfig);
|
||||
return appendClient(protocolConfig, clientName, container, credentials, serverController);
|
||||
}
|
||||
|
||||
return appendClient(protocolConfig.value(config_key::clientId).toString(), clientName, container, credentials, serverController);
|
||||
ErrorCode ClientManagementModel::appendClient(QJsonObject &protocolConfig, const QString &clientName, const DockerContainer container,
|
||||
const ServerCredentials &credentials, const QSharedPointer<ServerController> &serverController)
|
||||
{
|
||||
QString clientId;
|
||||
if (container == DockerContainer::Xray) {
|
||||
if (!protocolConfig.contains("outbounds")) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
QJsonArray outbounds = protocolConfig.value("outbounds").toArray();
|
||||
if (outbounds.isEmpty()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
QJsonObject outbound = outbounds[0].toObject();
|
||||
if (!outbound.contains("settings")) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
QJsonObject settings = outbound["settings"].toObject();
|
||||
if (!settings.contains("vnext")) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
QJsonArray vnext = settings["vnext"].toArray();
|
||||
if (vnext.isEmpty()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
QJsonObject vnextObj = vnext[0].toObject();
|
||||
if (!vnextObj.contains("users")) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
QJsonArray users = vnextObj["users"].toArray();
|
||||
if (users.isEmpty()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
QJsonObject user = users[0].toObject();
|
||||
if (!user.contains("id")) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
clientId = user["id"].toString();
|
||||
} else {
|
||||
clientId = protocolConfig.value(config_key::clientId).toString();
|
||||
}
|
||||
|
||||
return appendClient(clientId, clientName, container, credentials, serverController);
|
||||
}
|
||||
|
||||
ErrorCode ClientManagementModel::appendClient(const QString &clientId, const QString &clientName, const DockerContainer container,
|
||||
@@ -422,10 +536,27 @@ ErrorCode ClientManagementModel::revokeClient(const int row, const DockerContain
|
||||
auto client = m_clientsTable.at(row).toObject();
|
||||
QString clientId = client.value(configKey::clientId).toString();
|
||||
|
||||
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||
errorCode = revokeOpenVpn(row, container, credentials, serverIndex, serverController);
|
||||
} else if (container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
|
||||
errorCode = revokeWireGuard(row, container, credentials, serverController);
|
||||
switch(container)
|
||||
{
|
||||
case DockerContainer::OpenVpn:
|
||||
case DockerContainer::ShadowSocks:
|
||||
case DockerContainer::Cloak: {
|
||||
errorCode = revokeOpenVpn(row, container, credentials, serverIndex, serverController);
|
||||
break;
|
||||
}
|
||||
case DockerContainer::WireGuard:
|
||||
case DockerContainer::Awg: {
|
||||
errorCode = revokeWireGuard(row, container, credentials, serverController);
|
||||
break;
|
||||
}
|
||||
case DockerContainer::Xray: {
|
||||
errorCode = revokeXray(row, container, credentials, serverController);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
logger.error() << "Internal error: received unexpected container type";
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
}
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
@@ -463,19 +594,69 @@ ErrorCode ClientManagementModel::revokeClient(const QJsonObject &containerConfig
|
||||
}
|
||||
|
||||
Proto protocol;
|
||||
if (container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||
protocol = Proto::OpenVpn;
|
||||
} else if (container == DockerContainer::OpenVpn || container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
|
||||
protocol = ContainerProps::defaultProtocol(container);
|
||||
} else {
|
||||
return ErrorCode::NoError;
|
||||
|
||||
switch(container)
|
||||
{
|
||||
case DockerContainer::ShadowSocks:
|
||||
case DockerContainer::Cloak: {
|
||||
protocol = Proto::OpenVpn;
|
||||
break;
|
||||
}
|
||||
case DockerContainer::OpenVpn:
|
||||
case DockerContainer::WireGuard:
|
||||
case DockerContainer::Awg:
|
||||
case DockerContainer::Xray: {
|
||||
protocol = ContainerProps::defaultProtocol(container);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
logger.error() << "Internal error: received unexpected container type";
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
}
|
||||
|
||||
auto protocolConfig = ContainerProps::getProtocolConfigFromContainer(protocol, containerConfig);
|
||||
|
||||
QString clientId;
|
||||
if (container == DockerContainer::Xray) {
|
||||
if (!protocolConfig.contains("outbounds")) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
QJsonArray outbounds = protocolConfig.value("outbounds").toArray();
|
||||
if (outbounds.isEmpty()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
QJsonObject outbound = outbounds[0].toObject();
|
||||
if (!outbound.contains("settings")) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
QJsonObject settings = outbound["settings"].toObject();
|
||||
if (!settings.contains("vnext")) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
QJsonArray vnext = settings["vnext"].toArray();
|
||||
if (vnext.isEmpty()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
QJsonObject vnextObj = vnext[0].toObject();
|
||||
if (!vnextObj.contains("users")) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
QJsonArray users = vnextObj["users"].toArray();
|
||||
if (users.isEmpty()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
QJsonObject user = users[0].toObject();
|
||||
if (!user.contains("id")) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
clientId = user["id"].toString();
|
||||
} else {
|
||||
clientId = protocolConfig.value(config_key::clientId).toString();
|
||||
}
|
||||
|
||||
int row;
|
||||
bool clientExists = false;
|
||||
QString clientId = protocolConfig.value(config_key::clientId).toString();
|
||||
for (row = 0; row < rowCount(); row++) {
|
||||
auto client = m_clientsTable.at(row).toObject();
|
||||
if (clientId == client.value(configKey::clientId).toString()) {
|
||||
@@ -487,11 +668,28 @@ ErrorCode ClientManagementModel::revokeClient(const QJsonObject &containerConfig
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
||||
switch (container)
|
||||
{
|
||||
case DockerContainer::OpenVpn:
|
||||
case DockerContainer::ShadowSocks:
|
||||
case DockerContainer::Cloak: {
|
||||
errorCode = revokeOpenVpn(row, container, credentials, serverIndex, serverController);
|
||||
} else if (container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
|
||||
errorCode = revokeWireGuard(row, container, credentials, serverController);
|
||||
break;
|
||||
}
|
||||
case DockerContainer::WireGuard:
|
||||
case DockerContainer::Awg: {
|
||||
errorCode = revokeWireGuard(row, container, credentials, serverController);
|
||||
break;
|
||||
}
|
||||
case DockerContainer::Xray: {
|
||||
errorCode = revokeXray(row, container, credentials, serverController);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
logger.error() << "Internal error: received unexpected container type";
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
@@ -594,6 +792,117 @@ ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerCont
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode ClientManagementModel::revokeXray(const int row,
|
||||
const DockerContainer container,
|
||||
const ServerCredentials &credentials,
|
||||
const QSharedPointer<ServerController> &serverController)
|
||||
{
|
||||
ErrorCode error = ErrorCode::NoError;
|
||||
|
||||
// Get server config
|
||||
const QString serverConfigPath = amnezia::protocols::xray::serverConfigPath;
|
||||
const QString configString = serverController->getTextFileFromContainer(container, credentials, serverConfigPath, error);
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to get the xray server config file";
|
||||
return error;
|
||||
}
|
||||
|
||||
QJsonDocument serverConfig = QJsonDocument::fromJson(configString.toUtf8());
|
||||
if (serverConfig.isNull()) {
|
||||
logger.error() << "Failed to parse xray server config JSON";
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
// Get client ID to remove
|
||||
auto client = m_clientsTable.at(row).toObject();
|
||||
QString clientId = client.value(configKey::clientId).toString();
|
||||
|
||||
// Remove client from server config
|
||||
QJsonObject configObj = serverConfig.object();
|
||||
if (!configObj.contains("inbounds")) {
|
||||
logger.error() << "Missing inbounds in xray config";
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
QJsonArray inbounds = configObj["inbounds"].toArray();
|
||||
if (inbounds.isEmpty()) {
|
||||
logger.error() << "Empty inbounds array in xray config";
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
QJsonObject inbound = inbounds[0].toObject();
|
||||
if (!inbound.contains("settings")) {
|
||||
logger.error() << "Missing settings in xray inbound config";
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
QJsonObject settings = inbound["settings"].toObject();
|
||||
if (!settings.contains("clients")) {
|
||||
logger.error() << "Missing clients in xray settings";
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
QJsonArray clients = settings["clients"].toArray();
|
||||
if (clients.isEmpty()) {
|
||||
logger.error() << "Empty clients array in xray config";
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
for (int i = 0; i < clients.size(); ++i) {
|
||||
QJsonObject clientObj = clients[i].toObject();
|
||||
if (clientObj.contains("id") && clientObj["id"].toString() == clientId) {
|
||||
clients.removeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Update server config
|
||||
settings["clients"] = clients;
|
||||
inbound["settings"] = settings;
|
||||
inbounds[0] = inbound;
|
||||
configObj["inbounds"] = inbounds;
|
||||
|
||||
// Upload updated config
|
||||
error = serverController->uploadTextFileToContainer(
|
||||
container,
|
||||
credentials,
|
||||
QJsonDocument(configObj).toJson(),
|
||||
serverConfigPath
|
||||
);
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to upload updated xray config";
|
||||
return error;
|
||||
}
|
||||
|
||||
// Remove from local table
|
||||
beginRemoveRows(QModelIndex(), row, row);
|
||||
m_clientsTable.removeAt(row);
|
||||
endRemoveRows();
|
||||
|
||||
// Update clients table file on server
|
||||
const QByteArray clientsTableString = QJsonDocument(m_clientsTable).toJson();
|
||||
QString clientsTableFile = QString("/opt/amnezia/%1/clientsTable")
|
||||
.arg(ContainerProps::containerTypeToString(container));
|
||||
|
||||
error = serverController->uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to upload the clientsTable file";
|
||||
}
|
||||
|
||||
// Restart container
|
||||
QString restartScript = QString("sudo docker restart $CONTAINER_NAME");
|
||||
error = serverController->runScript(
|
||||
credentials,
|
||||
serverController->replaceVars(restartScript, serverController->genVarsForScript(credentials, container))
|
||||
);
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to restart xray container";
|
||||
return error;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ClientManagementModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
@@ -604,4 +913,4 @@ QHash<int, QByteArray> ClientManagementModel::roleNames() const
|
||||
roles[DataSentRole] = "dataSent";
|
||||
roles[AllowedIpsRole] = "allowedIps";
|
||||
return roles;
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,8 @@ public slots:
|
||||
const QSharedPointer<ServerController> &serverController);
|
||||
ErrorCode appendClient(const DockerContainer container, const ServerCredentials &credentials, const QJsonObject &containerConfig,
|
||||
const QString &clientName, const QSharedPointer<ServerController> &serverController);
|
||||
ErrorCode appendClient(QJsonObject &protocolConfig, const QString &clientName,const DockerContainer container,
|
||||
const ServerCredentials &credentials, const QSharedPointer<ServerController> &serverController);
|
||||
ErrorCode appendClient(const QString &clientId, const QString &clientName, const DockerContainer container,
|
||||
const ServerCredentials &credentials, const QSharedPointer<ServerController> &serverController);
|
||||
ErrorCode renameClient(const int row, const QString &userName, const DockerContainer container, const ServerCredentials &credentials,
|
||||
@@ -64,11 +66,15 @@ private:
|
||||
const QSharedPointer<ServerController> &serverController);
|
||||
ErrorCode revokeWireGuard(const int row, const DockerContainer container, const ServerCredentials &credentials,
|
||||
const QSharedPointer<ServerController> &serverController);
|
||||
ErrorCode revokeXray(const int row, const DockerContainer container, const ServerCredentials &credentials,
|
||||
const QSharedPointer<ServerController> &serverController);
|
||||
|
||||
ErrorCode getOpenVpnClients(const DockerContainer container, const ServerCredentials &credentials,
|
||||
const QSharedPointer<ServerController> &serverController, int &count);
|
||||
ErrorCode getWireGuardClients(const DockerContainer container, const ServerCredentials &credentials,
|
||||
const QSharedPointer<ServerController> &serverController, int &count);
|
||||
ErrorCode getXrayClients(const DockerContainer container, const ServerCredentials& credentials,
|
||||
const QSharedPointer<ServerController> &serverController, int &count);
|
||||
|
||||
ErrorCode wgShow(const DockerContainer container, const ServerCredentials &credentials,
|
||||
const QSharedPointer<ServerController> &serverController, std::vector<WgShowData> &data);
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace
|
||||
constexpr char serviceProtocol[] = "service_protocol";
|
||||
|
||||
constexpr char publicKeyInfo[] = "public_key";
|
||||
constexpr char endDate[] = "end_date";
|
||||
constexpr char expiresAt[] = "expires_at";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,9 @@ ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent)
|
||||
emit ServersModel::defaultServerNameChanged();
|
||||
updateDefaultServerContainersModel();
|
||||
});
|
||||
|
||||
connect(this, &ServersModel::processedServerIndexChanged, this, &ServersModel::processedServerChanged);
|
||||
connect(this, &ServersModel::dataChanged, this, &ServersModel::processedServerChanged);
|
||||
}
|
||||
|
||||
int ServersModel::rowCount(const QModelIndex &parent) const
|
||||
@@ -79,6 +82,12 @@ bool ServersModel::setData(const QModelIndex &index, const QVariant &value, int
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ServersModel::setData(const int index, const QVariant &value, int role)
|
||||
{
|
||||
QModelIndex modelIndex = this->index(index);
|
||||
return setData(modelIndex, value, role);
|
||||
}
|
||||
|
||||
QVariant ServersModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= static_cast<int>(m_servers.size())) {
|
||||
@@ -679,6 +688,18 @@ QVariant ServersModel::getProcessedServerData(const QString roleString)
|
||||
return {};
|
||||
}
|
||||
|
||||
bool ServersModel::setProcessedServerData(const QString &roleString, const QVariant &value)
|
||||
{
|
||||
const auto roles = roleNames();
|
||||
for (auto it = roles.begin(); it != roles.end(); it++) {
|
||||
if (QString(it.value()) == roleString) {
|
||||
return setData(m_processedServerIndex, value, it.key());
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ServersModel::isDefaultServerDefaultContainerHasSplitTunneling()
|
||||
{
|
||||
auto server = m_servers.at(m_defaultServerIndex).toObject();
|
||||
@@ -718,9 +739,9 @@ bool ServersModel::isApiKeyExpired(const int serverIndex)
|
||||
auto apiConfig = serverConfig.value(configKey::apiConfig).toObject();
|
||||
|
||||
auto publicKeyInfo = apiConfig.value(configKey::publicKeyInfo).toObject();
|
||||
const QString endDate = publicKeyInfo.value(configKey::endDate).toString();
|
||||
if (endDate.isEmpty()) {
|
||||
publicKeyInfo.insert(configKey::endDate, QDateTime::currentDateTimeUtc().addDays(1).toString(Qt::ISODate));
|
||||
const QString expiresAt = publicKeyInfo.value(configKey::expiresAt).toString();
|
||||
if (expiresAt.isEmpty()) {
|
||||
publicKeyInfo.insert(configKey::expiresAt, QDateTime::currentDateTimeUtc().addDays(1).toString(Qt::ISODate));
|
||||
apiConfig.insert(configKey::publicKeyInfo, publicKeyInfo);
|
||||
serverConfig.insert(configKey::apiConfig, apiConfig);
|
||||
editServer(serverConfig, serverIndex);
|
||||
@@ -728,8 +749,8 @@ bool ServersModel::isApiKeyExpired(const int serverIndex)
|
||||
return false;
|
||||
}
|
||||
|
||||
auto endDateDateTime = QDateTime::fromString(endDate, Qt::ISODate).toUTC();
|
||||
if (endDateDateTime < QDateTime::currentDateTimeUtc()) {
|
||||
auto expiresAtDateTime = QDateTime::fromString(expiresAt, Qt::ISODate).toUTC();
|
||||
if (expiresAtDateTime < QDateTime::currentDateTimeUtc()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -46,6 +46,7 @@ public:
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||
bool setData(const int index, const QVariant &value, int role = Qt::EditRole);
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
QVariant data(const int index, int role = Qt::DisplayRole) const;
|
||||
|
||||
@@ -115,6 +116,7 @@ public slots:
|
||||
QVariant getDefaultServerData(const QString roleString);
|
||||
|
||||
QVariant getProcessedServerData(const QString roleString);
|
||||
bool setProcessedServerData(const QString &roleString, const QVariant &value);
|
||||
|
||||
bool isDefaultServerDefaultContainerHasSplitTunneling();
|
||||
|
||||
@@ -127,6 +129,9 @@ protected:
|
||||
|
||||
signals:
|
||||
void processedServerIndexChanged(const int index);
|
||||
// emitted when the processed server index or processed server data is changed
|
||||
void processedServerChanged();
|
||||
|
||||
void defaultServerIndexChanged(const int index);
|
||||
void defaultServerNameChanged();
|
||||
void defaultServerDescriptionChanged();
|
||||
|
||||
@@ -5,13 +5,12 @@
|
||||
#include <QDebug>
|
||||
#include "notificationhandler.h"
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS)
|
||||
# include "platforms/ios/iosnotificationhandler.h"
|
||||
#else
|
||||
# include "systemtray_notificationhandler.h"
|
||||
#endif
|
||||
|
||||
|
||||
// static
|
||||
NotificationHandler* NotificationHandler::create(QObject* parent) {
|
||||
#if defined(Q_OS_IOS)
|
||||
|
||||
@@ -16,6 +16,32 @@ Button {
|
||||
property string connectedButtonColor: AmneziaStyle.color.goldenApricot
|
||||
property bool buttonActiveFocus: activeFocus && (Qt.platform.os !== "android" || SettingsController.isOnTv())
|
||||
|
||||
property bool isFocusable: true
|
||||
|
||||
Keys.onTabPressed: {
|
||||
FocusController.nextKeyTabItem()
|
||||
}
|
||||
|
||||
Keys.onBacktabPressed: {
|
||||
FocusController.previousKeyTabItem()
|
||||
}
|
||||
|
||||
Keys.onUpPressed: {
|
||||
FocusController.nextKeyUpItem()
|
||||
}
|
||||
|
||||
Keys.onDownPressed: {
|
||||
FocusController.nextKeyDownItem()
|
||||
}
|
||||
|
||||
Keys.onLeftPressed: {
|
||||
FocusController.nextKeyLeftItem()
|
||||
}
|
||||
|
||||
Keys.onRightPressed: {
|
||||
FocusController.nextKeyRightItem()
|
||||
}
|
||||
|
||||
implicitWidth: 190
|
||||
implicitHeight: 190
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ DrawerType2 {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
expandedContent: ColumnLayout {
|
||||
expandedStateContent: ColumnLayout {
|
||||
id: content
|
||||
|
||||
anchors.top: parent.top
|
||||
@@ -26,14 +26,6 @@ DrawerType2 {
|
||||
root.expandedHeight = content.implicitHeight + 32
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
enabled: !GC.isMobile()
|
||||
function onOpened() {
|
||||
focusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
Header2Type {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
@@ -44,11 +36,6 @@ DrawerType2 {
|
||||
headerText: qsTr("Add new connection")
|
||||
}
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: ip.rightButton
|
||||
}
|
||||
|
||||
LabelWithButtonType {
|
||||
id: ip
|
||||
Layout.fillWidth: true
|
||||
@@ -59,10 +46,8 @@ DrawerType2 {
|
||||
|
||||
clickedFunction: function() {
|
||||
PageController.goToPage(PageEnum.PageSetupWizardCredentials)
|
||||
root.close()
|
||||
root.closeTriggered()
|
||||
}
|
||||
|
||||
KeyNavigation.tab: qrCode.rightButton
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
@@ -76,10 +61,8 @@ DrawerType2 {
|
||||
|
||||
clickedFunction: function() {
|
||||
PageController.goToPage(PageEnum.PageSetupWizardConfigSource)
|
||||
root.close()
|
||||
root.closeTriggered()
|
||||
}
|
||||
|
||||
KeyNavigation.tab: focusItem
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
|
||||
@@ -17,55 +17,15 @@ ListView {
|
||||
property var rootWidth
|
||||
property var selectedText
|
||||
|
||||
property bool a: true
|
||||
|
||||
width: rootWidth
|
||||
height: menuContent.contentItem.height
|
||||
height: contentItem.height
|
||||
|
||||
clip: true
|
||||
interactive: false
|
||||
snapMode: ListView.SnapToItem
|
||||
|
||||
property FlickableType parentFlickable
|
||||
property var lastItemTabClicked
|
||||
ScrollBar.vertical: ScrollBarType {}
|
||||
|
||||
property int currentFocusIndex: 0
|
||||
|
||||
activeFocusOnTab: true
|
||||
onActiveFocusChanged: {
|
||||
if (activeFocus) {
|
||||
this.currentFocusIndex = 0
|
||||
this.itemAtIndex(currentFocusIndex).forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onTabPressed: {
|
||||
if (currentFocusIndex < this.count - 1) {
|
||||
currentFocusIndex += 1
|
||||
this.itemAtIndex(currentFocusIndex).forceActiveFocus()
|
||||
} else {
|
||||
currentFocusIndex = 0
|
||||
if (lastItemTabClicked && typeof lastItemTabClicked === "function") {
|
||||
lastItemTabClicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
currentFocusIndex = 0
|
||||
focusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
}
|
||||
|
||||
onCurrentFocusIndexChanged: {
|
||||
if (parentFlickable) {
|
||||
parentFlickable.ensureVisible(this.itemAtIndex(currentFocusIndex))
|
||||
}
|
||||
}
|
||||
property bool isFocusable: true
|
||||
|
||||
ButtonGroup {
|
||||
id: containersRadioButtonGroup
|
||||
@@ -75,12 +35,6 @@ ListView {
|
||||
implicitWidth: rootWidth
|
||||
implicitHeight: content.implicitHeight
|
||||
|
||||
onActiveFocusChanged: {
|
||||
if (activeFocus) {
|
||||
containerRadioButton.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
|
||||
@@ -111,13 +65,13 @@ ListView {
|
||||
}
|
||||
|
||||
if (checked) {
|
||||
containersDropDown.close()
|
||||
containersDropDown.closeTriggered()
|
||||
ServersModel.setDefaultContainer(ServersModel.defaultIndex, proxyDefaultServerContainersModel.mapToSource(index))
|
||||
} else {
|
||||
ContainersModel.setProcessedContainerIndex(proxyDefaultServerContainersModel.mapToSource(index))
|
||||
InstallController.setShouldCreateServer(false)
|
||||
PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
|
||||
containersDropDown.close()
|
||||
containersDropDown.closeTriggered()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||