Compare commits

...

104 Commits

Author SHA1 Message Date
lollipopkit🏳️‍⚧️
a3b48fc01c chore: bump version 2024-07-26 23:35:59 +08:00
lollipopkit🏳️‍⚧️
8be94aa09c feat: use $EDITOR to edit files (#496)
Fixes #489
2024-07-26 23:32:57 +08:00
lollipopkit🏳️‍⚧️
5db1253ab8 fix: termux compatibility (#495) 2024-07-26 22:31:17 +08:00
lollipopkit🏳️‍⚧️
ceedd86310 rm: pkg (#494)
Fixes #470
2024-07-26 21:31:45 +08:00
lollipopkit🏳️‍⚧️
6a0254623f opt.: json input experience 2024-07-26 20:22:30 +08:00
lollipopkit🏳️‍⚧️
1c6ec56032 Create FUNDING.yml 2024-07-25 10:42:18 +08:00
lollipopkit🏳️‍⚧️
287869ed45 opt.: simplify settings page (#488) 2024-07-24 00:30:17 +08:00
lollipopkit🏳️‍⚧️
e4dbc3ba12 feat: set envs in term (#485) 2024-07-23 21:34:34 +08:00
lollipopkit🏳️‍⚧️
426e5689f8 fix: uploaded file's path on windows (#484) 2024-07-23 19:59:58 +08:00
lollipopkit🏳️‍⚧️
afda5fd4a4 fix: bio auth (#482) 2024-07-23 19:26:03 +08:00
lollipopkit🏳️‍⚧️
0a21b2820c fix: letterCacheTip translation 2024-07-23 12:14:31 +08:00
lollipopkit🏳️‍⚧️
87b3b76b0b feat: display cpu model (#477) 2024-07-23 12:03:10 +08:00
lollipopkit🏳️‍⚧️
41ec46f1d3 opt.: show loading dialog 2024-07-22 23:33:21 +08:00
lollipopkit🏳️‍⚧️
7a359588db opt.: input field suggestion 2024-07-22 22:03:56 +08:00
lollipopkit🏳️‍⚧️
255abe8b11 rollback: write script to /dev/shm (#474) 2024-07-21 17:58:14 +08:00
lollipopkit🏳️‍⚧️
b0936c5e6e fix: termux compatibility (#472) 2024-07-20 20:35:30 +08:00
lollipopkit🏳️‍⚧️
2907ac74d4 chore: bump version 2024-07-18 23:44:01 +08:00
lollipopkit🏳️‍⚧️
ea678f37b0 chore: bump version 2024-07-18 23:15:40 +08:00
lollipopkit🏳️‍⚧️
076082c945 feat: sftp perm setting & path copy (#467) 2024-07-18 21:40:40 +08:00
lollipopkit🏳️‍⚧️
5ee98f90e8 fix: update changelog (#466) 2024-07-18 20:53:22 +08:00
lollipopkit🏳️‍⚧️
c988dd88d7 fix: linux duplicated title bar (#462)
Fixes #459
2024-07-15 17:38:30 +08:00
lollipopkit🏳️‍⚧️
f7d6c461dc fix: version display (#458)
Fixes #457
2024-07-10 15:12:05 +08:00
lollipopkit🏳️‍⚧️
14771ae946 chore: README 2024-07-09 14:36:04 +08:00
lollipopkit🏳️‍⚧️
7e9086b20e fix: chmod perm 2024-07-09 14:02:23 +08:00
Noo6
4b3c4870ba fix: desktop window appbar (#450) 2024-07-05 12:42:38 +08:00
Noo6
43cebd0c04 fix: window blink on startup (#447) 2024-07-04 12:23:20 +08:00
Noo6
5ce13109b0 fix: ssh card tap area (#448) 2024-07-04 12:22:19 +08:00
lollipopkit🏳️‍⚧️
6e428c91d1 feat: disable letter cache (#446)
Fixes #445
2024-07-03 19:55:33 +08:00
lollipopkit🏳️‍⚧️
4430045550 feat: write script into /dev/shm (#444)
Fixes #443
2024-07-03 19:14:27 +08:00
lollipopkit🏳️‍⚧️
282cb06091 fix: picker dialog (#442)
Fixes #440
2024-07-03 18:19:09 +08:00
lollipopkit🏳️‍⚧️
772c2743b5 fix: no appBar in server detail page (#441)
Fixes #435
2024-07-03 16:42:52 +08:00
lollipopkit🏳️‍⚧️
90199b89a5 chore: README 2024-07-03 00:52:28 +08:00
Integral
e1d2e3f3e5 l10n: fix remaining translations (#439)
* l10n: Url -> URL

* l10n: Logo Address -> Logo URL

* l10n: fix ttl translation

* l10n: fix all zh-tw translations

* l10n: fix all zh-cn translations

* l10n: fix all en translations
2024-07-02 15:02:49 +00:00
Integral
3f9fe1f2c6 l10n: alterUrl -> fallbackSshDest (#437) 2024-07-02 13:15:19 +00:00
Integral
c79bbc5756 l10n: fix two acronyms (MAC, URL) (#436)
* l10n: Mac Address -> MAC Address

* l10n: PVE addr -> URL
2024-07-01 14:56:38 +00:00
Integral
63e1bec2b9 l10n: fix translation of net/network (#433) 2024-07-01 07:01:51 +00:00
Integral
d26b7c6f75 l10n: add noLineChartForCpu field (#431) 2024-07-01 05:24:31 +00:00
Integral
da8dc4fa54 docs(README): add f-droid & reorganize other installation methods (#429)
* docs(README): add f-droid & reorganize other installation methods

* docs(README): update Chinese README from English
2024-06-30 11:51:36 +00:00
Integral
413b81c47f l10n: fix Japanese translations (#425) 2024-06-25 16:00:42 +00:00
Integral
9ef419e3df l10n: fix English translations (#424) 2024-06-25 16:00:26 +00:00
Integral
39893912d9 Merge pull request #423 from Integral-Tech/fix-fdroid-typo
chore: fix typo of "F-Droid"
2024-06-25 14:04:16 +00:00
Integral
49456ca6c3 chore: fix typo of "F-Droid" 2024-06-25 22:00:46 +08:00
lollipopkit🏳️‍⚧️
6b9b8f0dbb chore: bump version 2024-06-25 13:15:29 +08:00
lollipopkit🏳️‍⚧️
5eb48b2717 fix: linux build (#422)
Fixes #421
2024-06-25 11:48:56 +08:00
lollipopkit🏳️‍⚧️
5339cfca70 chore: lib vers bump (#420)
Fixes #419
2024-06-25 11:16:34 +08:00
lollipopkit🏳️‍⚧️
1462b2d0b8 fix: always enter intro page (#418)
Fixes #417
2024-06-24 16:32:37 +08:00
lollipopkit🏳️‍⚧️
3798a23183 chore: bump version 2024-06-24 00:56:45 +08:00
lollipopkit🏳️‍⚧️
ddaf916170 feat: intro page (#416)
Fixes #415
2024-06-24 00:43:52 +08:00
lollipopkit🏳️‍⚧️
d6e37b058f fix: docker parse (#414)
Fixes #395
2024-06-23 18:37:05 +08:00
lollipopkit🏳️‍⚧️
2e9ad7d7cb chore: missing l10n noLineChart (#413)
Fixes #412
2024-06-23 15:39:30 +08:00
lollipopkit🏳️‍⚧️
190da74f66 chore: add participants (#410)
Fixes #409
2024-06-23 00:27:26 +08:00
lollipopkit🏳️‍⚧️
f1315dda7f fix: batch delete servers (#408)
Fixes #393
2024-06-23 00:24:30 +08:00
lollipopkit🏳️‍⚧️
43e6105eb3 fix: hideTitleBar doesn't work (#407)
Fixes #406
2024-06-22 22:58:22 +08:00
lollipopkit🏳️‍⚧️
d785209eb6 opt.: share on desktop (#405) 2024-06-22 22:50:17 +08:00
lollipopkit🏳️‍⚧️
da8b6a9010 feat: remember window size (#404)
Fixes #398
2024-06-22 21:52:48 +08:00
lollipopkit🏳️‍⚧️
1fd68722da fix: watchos settings (#403)
Fixes #401
2024-06-22 21:09:05 +08:00
lollipopkit🏳️‍⚧️
c9a2c1d0e4 Android - default to English (#402) 2024-06-18 14:39:18 +08:00
lollipopkit
161f536a62 fix: conform fdroid version fmt
Signed-off-by: lollipopkit <10864310+lollipopkit@users.noreply.github.com>
2024-06-13 23:51:10 +08:00
lollipopkit
1a32e9944e opt.: put version logic somewhere else (#381)
Signed-off-by: lollipopkit <10864310+lollipopkit@users.noreply.github.com>
2024-06-13 22:40:18 +08:00
lollipopkit
6deb753198 fix: version change logic (#381) 2024-06-13 21:29:03 +08:00
lollipopkit
4e33a98631 chore: fl_build 2024-06-13 21:22:44 +08:00
lollipopkit
dcb9464d8f fix
Signed-off-by: lollipopkit <10864310+lollipopkit@users.noreply.github.com>
2024-06-13 20:39:06 +08:00
lollipopkit
b94936b29f fix: reproducible (#381)
Signed-off-by: lollipopkit <10864310+lollipopkit@users.noreply.github.com>
2024-06-13 20:28:22 +08:00
lollipopkit
108d0a5a5b chore: bump version
Signed-off-by: lollipopkit <10864310+lollipopkit@users.noreply.github.com>
2024-06-13 00:45:24 +08:00
Integral
4814a2de28 Merge pull request #391 from Integral-Tech/add-abiCodes
Add abiCodes
2024-06-12 16:21:13 +00:00
Integral
5d8eeff502 Add abiCodes 2024-06-13 00:18:04 +08:00
lollipopkit
0bc4087266 chore: correct version for fdroid 2024-06-13 00:00:20 +08:00
lollipopkit
921209b901 chore: specify flutter version (#381) 2024-06-12 19:51:04 +08:00
lollipopkit
fa9d754470 rm: android wear settings 2024-06-12 19:42:38 +08:00
Integral
1f50a1f0f4 Merge pull request #389 from Integral-Tech/clean-up-proguard-rules
fix: clean up proguard-rules to remove depends on google libraries
2024-06-11 18:03:44 +00:00
Integral
80e84c0421 fix: clean up proguard-rules to remove depends on google libraries 2024-06-12 01:36:29 +08:00
lollipopkit
5059872c3f chore: README 2024-06-11 22:54:48 +08:00
lollipopkit
8add244776 fix: fdroid version fmt 2024-06-11 22:47:48 +08:00
lollipopkit
04e23fd7e4 fix: pubspec version 2024-06-11 22:18:27 +08:00
lollipopkit
336b11b808 chore: change dart pkg id 2024-06-11 22:06:29 +08:00
lollipopkit
8d9dba361c chore: completely rm countly 2024-06-11 22:03:17 +08:00
Integral
64ce3638cb chore: add distributionSha256Sum in gradle (#385) 2024-06-11 18:43:41 +08:00
lollipopkit
f3ceb73f0e fix: rm gms (#379 #381) 2024-06-11 16:40:05 +08:00
Integral
131dbe934c chore: setup fastlane for F-Droid submission (#384) 2024-06-11 16:18:39 +08:00
lollipopkit
58288e89bd Merge branch 'main' of github.com:lollipopkit/flutter_server_box 2024-06-10 21:35:59 +08:00
lollipopkit🏳️‍⚧️
22c43c7124 Lollipopkit/issue382 (#383) 2024-06-10 21:34:56 +08:00
lollipopkit
2bf0b25ee5 fix: podman term 2024-06-10 21:32:45 +08:00
lollipopkit
3bc03c1364 opt.: add tip (#380 #382) 2024-06-10 21:29:41 +08:00
lollipopkit
490d71f8c9 feat: snippet with term ctrl (#380 #382) 2024-06-10 21:08:33 +08:00
lollipopkit
edceb5900e opt.: write script to server tip 2024-06-09 13:57:02 +08:00
lollipopkit
e5ef28415b opt.: ssh tab 2024-06-08 21:39:42 +08:00
lollipopkit
46b98df153 Merge branch 'dev' 2024-06-08 20:58:41 +08:00
lollipopkit
9f34021c90 fix: docker ps parse if id/name is too long 2024-06-08 20:57:56 +08:00
lollipopkit
8121eef839 opt.: RNode 2024-06-08 15:35:19 +08:00
lollipopkit
da48d1f66c opt.: IME popup after opening drawer if ssh term is focusing 2024-06-08 13:53:23 +08:00
lollipopkit
b167287c5b opt.: ssh tab page's tab bar 2024-06-07 23:53:13 +08:00
lollipopkit
41f9da6bf8 fix: ssh tab PageView animteToPage 2024-06-07 21:51:00 +08:00
lollipopkit
e7c7fc8186 fix: ssh tab name generaton 2024-06-07 21:43:38 +08:00
lollipopkit
b950dd2d68 fix: ssh tab 2024-06-07 21:09:17 +08:00
lollipopkit
6d34de14d3 Merge branch 'dev' 2024-06-06 21:26:03 +08:00
lollipopkit
a5a84c0cdd fix: podman log 2024-06-06 18:52:20 +08:00
lollipopkit
701b1b811f feat: beta program 2024-06-06 16:18:10 +08:00
lollipopkit
97267cdfbf fix: docker container status (#374) 2024-06-05 21:58:19 +08:00
lollipopkit
40ce37d230 opt.: sftp del dir 2024-06-05 18:48:44 +08:00
lollipopkit
8a9ade355c fix: update check 2024-06-05 18:26:02 +08:00
lollipopkit
9bffec64b5 fix: wol cfg (#373) 2024-06-05 18:16:17 +08:00
lollipopkit
a03ee2ae0e fix: term help 2024-06-05 11:12:43 +08:00
PaperCube
ee889235fe Fixed UI representation of server reorder page (#372) 2024-06-04 18:57:57 +01:00
lollipopkit
94d6d80497 chore: README 2024-06-04 23:17:32 +08:00
153 changed files with 3113 additions and 1865 deletions

14
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,14 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: lollipopkit
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
custom: ['https://afdian.com/a/lollipopkit'] # Replace with up to 4 custom sponsorship URLs

View File

@@ -15,10 +15,11 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
with:
fetch-depth: '0'
- name: Install Flutter - name: Install Flutter
uses: subosito/flutter-action@v2 uses: subosito/flutter-action@v2
with:
channel: 'stable'
flutter-version: '3.22.2'
- uses: actions/setup-java@v4 - uses: actions/setup-java@v4
with: with:
distribution: 'zulu' distribution: 'zulu'
@@ -29,13 +30,18 @@ jobs:
curl -u ${{ secrets.BASIC_AUTH }} -o android/key.properties ${{ secrets.URL_PREFIX }}key.properties curl -u ${{ secrets.BASIC_AUTH }} -o android/key.properties ${{ secrets.URL_PREFIX }}key.properties
- name: Build - name: Build
run: dart run fl_build -p android,linux run: dart run fl_build -p android,linux
- name: Rename for fdroid
run: |
mv build/app/outputs/flutter-apk/${{ env.APP_NAME }}_${{ env.BUILD_NUMBER }}_arm64.apk build/app/outputs/flutter-apk/${{ env.APP_NAME }}_v1.0.${{ env.BUILD_NUMBER }}_arm64.apk
mv build/app/outputs/flutter-apk/${{ env.APP_NAME }}_${{ env.BUILD_NUMBER }}_arm.apk build/app/outputs/flutter-apk/${{ env.APP_NAME }}_v1.0.${{ env.BUILD_NUMBER }}_arm.apk
mv build/app/outputs/flutter-apk/${{ env.APP_NAME }}_${{ env.BUILD_NUMBER }}_amd64.apk build/app/outputs/flutter-apk/${{ env.APP_NAME }}_v1.0.${{ env.BUILD_NUMBER }}_amd64.apk
- name: Create Release - name: Create Release
uses: softprops/action-gh-release@v2 uses: softprops/action-gh-release@v2
with: with:
files: | files: |
build/app/outputs/flutter-apk/${{ env.APP_NAME }}_${{ env.BUILD_NUMBER }}_arm64.apk build/app/outputs/flutter-apk/${{ env.APP_NAME }}_v1.0.${{ env.BUILD_NUMBER }}_arm64.apk
build/app/outputs/flutter-apk/${{ env.APP_NAME }}_${{ env.BUILD_NUMBER }}_arm.apk build/app/outputs/flutter-apk/${{ env.APP_NAME }}_v1.0.${{ env.BUILD_NUMBER }}_arm.apk
build/app/outputs/flutter-apk/${{ env.APP_NAME }}_${{ env.BUILD_NUMBER }}_amd64.apk build/app/outputs/flutter-apk/${{ env.APP_NAME }}_v1.0.${{ env.BUILD_NUMBER }}_amd64.apk
${{ env.APP_NAME }}_${{ env.BUILD_NUMBER }}_amd64.AppImage ${{ env.APP_NAME }}_${{ env.BUILD_NUMBER }}_amd64.AppImage
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -46,8 +52,6 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
with:
fetch-depth: '0'
- name: Install Flutter - name: Install Flutter
uses: subosito/flutter-action@v2 uses: subosito/flutter-action@v2
- name: Build - name: Build
@@ -68,6 +72,9 @@ jobs:
# uses: actions/checkout@v4 # uses: actions/checkout@v4
# - name: Install Flutter # - name: Install Flutter
# uses: subosito/flutter-action@v2 # uses: subosito/flutter-action@v2
# with:
# channel: 'stable'
# flutter-version: '3.22.2'
# - name: Build # - name: Build
# run: dart run fl_build -p ios,mac # run: dart run fl_build -p ios,mac
# - name: Create Release # - name: Create Release

3
.gitignore vendored
View File

@@ -57,9 +57,10 @@ test.dart
# Linux release # Linux release
linux.AppDir linux.AppDir
ServerBox-x86_64.AppImage **/*.AppImage
untranlated.json untranlated.json
.vscode/settings.json .vscode/settings.json
more_build_data.json more_build_data.json
trans.txt

View File

@@ -4,7 +4,7 @@
# This file should be version controlled and should not be manually edited. # This file should be version controlled and should not be manually edited.
version: version:
revision: "bae5e49bc2a867403c43b2aae2de8f8c33b037e4" revision: "761747bfc538b5af34aa0d3fac380f1bc331ec49"
channel: "stable" channel: "stable"
project_type: app project_type: app
@@ -13,26 +13,26 @@ project_type: app
migration: migration:
platforms: platforms:
- platform: root - platform: root
create_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
base_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
- platform: android - platform: android
create_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
base_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
- platform: ios - platform: ios
create_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
base_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
- platform: linux - platform: linux
create_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
base_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
- platform: macos - platform: macos
create_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
base_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
- platform: web - platform: web
create_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
base_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
- platform: windows - platform: windows
create_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
base_revision: bae5e49bc2a867403c43b2aae2de8f8c33b037e4 base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
# User provided section # User provided section

4
.vscode/launch.json vendored
View File

@@ -8,6 +8,10 @@
"name": "debug", "name": "debug",
"request": "launch", "request": "launch",
"type": "dart", "type": "dart",
"env": {
// Comment this line to use the default display
"DISPLAY": ":1"
}
// "args": [ // "args": [
// "-v" // "-v"
// ] // ]

View File

@@ -4,7 +4,6 @@ English | [简体中文](README_zh.md)
<p align="center"> <p align="center">
<img alt="lang" src="https://img.shields.io/badge/lang-dart-pink"> <img alt="lang" src="https://img.shields.io/badge/lang-dart-pink">
<img alt="countly" src="https://img.shields.io/badge/analysis-countly-pink">
<img alt="license" src="https://img.shields.io/badge/license-GPLv3-pink"> <img alt="license" src="https://img.shields.io/badge/license-GPLv3-pink">
</p> </p>
@@ -14,14 +13,23 @@ A Flutter project which provide charts to display <a href="../../issues/43">Linu
Especially thanks to <a href="https://github.com/TerminalStudio/dartssh2">dartssh2</a> & <a href="https://github.com/TerminalStudio/xterm.dart">xterm.dart</a>. Especially thanks to <a href="https://github.com/TerminalStudio/dartssh2">dartssh2</a> & <a href="https://github.com/TerminalStudio/xterm.dart">xterm.dart</a>.
</p> </p>
## ⬇️ Download
🎉 **The `Android / Linux / Windows` version are now built via GitHub Actions**
[iOS & macOS](https://apps.apple.com/app/id6476033062) / [Android & Linux & Windows](https://github.com/lollipopkit/flutter_gpt_box/releases) ## 📥 Install
Platform | From
--- | ---
iOS / macOS | [AppStore](https://apps.apple.com/app/id1586449703)
Android | [GitHub](https://github.com/lollipopkit/flutter_server_box/releases) / [CDN](https://cdn.lolli.tech/serverbox/?sort=time&order=desc&layout=grid) / [F-Droid](https://f-droid.org/packages/tech.lolli.toolbox) / [OpenAPK](https://www.openapk.net/serverbox/tech.lolli.toolbox/)
Linux / Windows | [GitHub](https://github.com/lollipopkit/flutter_server_box/releases) / [CDN](https://cdn.lolli.tech/serverbox/?sort=time&order=desc&layout=grid)
**Please only download pkgs from the source that you trust!**
- `AppStore` & `CDN` packages are built by myself
- Github releases are built by Github Actions
- Other sources are built by themselves
## 🔖 Feature ## 🔖 Feature
- `Status chart` (CPU, Sensors, GPU...), `SSH` Term, `SFTP`, `Docker & Pkg & Process`... - `Status chart` (CPU, Sensors, GPU...), `SSH` Term, `SFTP`, `Docker & Process`...
- Platform specific: `Bio auth``Msg push``Home widget``watchOS App`... - Platform specific: `Bio auth``Msg push``Home widget``watchOS App`...
- English, 简体中文; Deutsch [@its-tom](https://github.com/its-tom), 繁體中文 [@kalashnikov](https://github.com/kalashnikov), Indonesian [@azkadev](https://github.com/azkadev), Français [@FrancXPT](https://github.com/FrancXPT), Dutch [@QazCetelic](https://github.com/QazCetelic); Español, Русский язык, Português, 日本語 (Generated by GPT) - English, 简体中文; Deutsch [@its-tom](https://github.com/its-tom), 繁體中文 [@kalashnikov](https://github.com/kalashnikov), Indonesian [@azkadev](https://github.com/azkadev), Français [@FrancXPT](https://github.com/FrancXPT), Dutch [@QazCetelic](https://github.com/QazCetelic); Español, Русский язык, Português, 日本語 (Generated by GPT)
@@ -29,16 +37,14 @@ Especially thanks to <a href="https://github.com/TerminalStudio/dartssh2">dartss
## 🏙️ ScreenShots ## 🏙️ ScreenShots
<table> <table>
<tr> <tr>
<td><img width="277px" src="imgs/server.png"></td> <td><img width="277px" src="https://cdn.lolli.tech/serverbox/screenshot/1.png"></td>
<td><img width="277px" src="imgs/detail.png"></td> <td><img width="277px" src="https://cdn.lolli.tech/serverbox/screenshot/2.png"></td>
<td><img width="277px" src="imgs/sftp.png"></td> <td><img width="277px" src="https://cdn.lolli.tech/serverbox/screenshot/3.png"></td>
</tr> </tr>
</table>
<table>
<tr> <tr>
<td><img width="277px" src="imgs/editor.png"> </td> <td><img width="277px" src="https://cdn.lolli.tech/serverbox/screenshot/4.png"> </td>
<td><img width="277px" src="imgs/ssh.png"></td> <td><img width="277px" src="https://cdn.lolli.tech/serverbox/screenshot/5.png"></td>
<td><img width="277px" src="imgs/docker.png"></td> <td><img width="277px" src="https://cdn.lolli.tech/serverbox/screenshot/6.png"></td>
</tr> </tr>
</table> </table>
@@ -56,8 +62,16 @@ After you read the above, you can open an [issue](https://github.com/lollipopkit
## 🧱 Contribution ## 🧱 Contribution
- Any positive contribution is welcome. Any positive contribution is welcome.
- [l10n guide](https://blog.lolli.tech/faq/) can be found in my blog.
### Development
1. Setup [Flutter](https://flutter.dev/docs/get-started/install) environment.
2. Clone this repo, run `flutter run` to start the app.
3. Run `dart run fl_build -p PLATFORM` to build the app.
### Translation
- [Guide](https://blog.lpkt.cn/posts/faq/) can be found in my blog.
- We need your help! Just feel free to open a PR.
## 💡 My other apps ## 💡 My other apps

View File

@@ -4,7 +4,6 @@
<p align="center"> <p align="center">
<img alt="lang" src="https://img.shields.io/badge/lang-dart-pink"> <img alt="lang" src="https://img.shields.io/badge/lang-dart-pink">
<img alt="countly" src="https://img.shields.io/badge/analysis-countly-pink">
<img alt="license" src="https://img.shields.io/badge/license-GPLv3-pink"> <img alt="license" src="https://img.shields.io/badge/license-GPLv3-pink">
</p> </p>
@@ -14,15 +13,22 @@
特别感谢 <a href="https://github.com/TerminalStudio/dartssh2">dartssh2</a> & <a href="https://github.com/TerminalStudio/xterm.dart">xterm.dart</a> 特别感谢 <a href="https://github.com/TerminalStudio/dartssh2">dartssh2</a> & <a href="https://github.com/TerminalStudio/xterm.dart">xterm.dart</a>
</p> </p>
## 📥 安装
## ⬇️ Download 平台 | 下载
🎉 **现在 `Android / Linux / Windows` 版本使用 GitHub Actions 构建** --- | ---
iOS / macOS | [AppStore](https://apps.apple.com/app/id1586449703)
Android | [GitHub](https://github.com/lollipopkit/flutter_server_box/releases) / [CDN](https://cdn.lolli.tech/serverbox/?sort=time&order=desc&layout=grid) / [F-Droid](https://f-droid.org/packages/tech.lolli.toolbox) / [OpenAPK](https://www.openapk.net/serverbox/tech.lolli.toolbox/)
Linux / Windows | [GitHub](https://github.com/lollipopkit/flutter_server_box/releases) / [CDN](https://cdn.lolli.tech/serverbox/?sort=time&order=desc&layout=grid)
[iOS & macOS](https://apps.apple.com/app/id1586449703) / [Android & Linux & Windows](https://github.com/lollipopkit/flutter_gpt_box/releases) **请不要从不受信任的来源下载!**
- `AppStore` & `CDN` 的包由我构建
- Github 的包由 Github Actions 构建
- 其他来源由其所有者构建
## 🔖 特点 ## 🔖 特点
- `状态图表`CPU、传感器、GPU 等), `SSH` 终端, `SFTP`, `Docker & 包 & 进程` 管理... - `状态图表`CPU、传感器、GPU 等), `SSH` 终端, `SFTP`, `Docker & 进程` 管理...
- 特殊支持:`生物认证``推送``桌面小部件``watchOS App``跟随系统颜色`... - 特殊支持:`生物认证``推送``桌面小部件``watchOS App``跟随系统颜色`...
- 本地化 - 本地化
- English, 简体中文 - English, 简体中文
@@ -33,16 +39,14 @@
## 🏙️ 截屏 ## 🏙️ 截屏
<table> <table>
<tr> <tr>
<td><img width="277px" src="imgs/server.png"></td> <td><img width="277px" src="https://cdn.lolli.tech/serverbox/screenshot/1.png"></td>
<td><img width="277px" src="imgs/detail.png"></td> <td><img width="277px" src="https://cdn.lolli.tech/serverbox/screenshot/2.png"></td>
<td><img width="277px" src="imgs/sftp.png"></td> <td><img width="277px" src="https://cdn.lolli.tech/serverbox/screenshot/3.png"></td>
</tr> </tr>
</table>
<table>
<tr> <tr>
<td><img width="277px" src="imgs/editor.png"> </td> <td><img width="277px" src="https://cdn.lolli.tech/serverbox/screenshot/4.png"> </td>
<td><img width="277px" src="imgs/ssh.png"></td> <td><img width="277px" src="https://cdn.lolli.tech/serverbox/screenshot/5.png"></td>
<td><img width="277px" src="imgs/docker.png"></td> <td><img width="277px" src="https://cdn.lolli.tech/serverbox/screenshot/6.png"></td>
</tr> </tr>
</table> </table>
@@ -62,9 +66,15 @@
## 🧱 贡献 ## 🧱 贡献
- 任何正面的贡献都欢迎。 任何正面的贡献都欢迎。
- [本地化翻译指南](https://blog.lolli.tech/faq/) 可在我的博客中找到。
### 开发
1. 安装 [Flutter](https://flutter.dev/docs/get-started/install)
2. 克隆这个仓库, 运行 `flutter run` 启动应用
3. 运行 `dart run fl_build -p PLATFORM` 构建应用
### 翻译
[指南](https://blog.lolli.tech/faq/) 可在我的博客中找到。
## 💡 我的其它 Apps ## 💡 我的其它 Apps
- [GPT Box](https://github.com/lollipopkit/flutter_gpt_box) - 支持 OpenAI API 的 第三方全平台客户端。 - [GPT Box](https://github.com/lollipopkit/flutter_gpt_box) - 支持 OpenAI API 的 第三方全平台客户端。

View File

@@ -100,3 +100,14 @@ flutter {
} }
dependencies {} dependencies {}
ext.abiCodes = ["x86_64": 1, "armeabi-v7a": 2, "arm64-v8a": 3]
import com.android.build.OutputFile
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def abiVersionCode = project.ext.abiCodes.get(output.getFilter(OutputFile.ABI))
if (abiVersionCode != null) {
output.versionCodeOverride = variant.versionCode * 10 + abiVersionCode
}
}
}

View File

@@ -1,7 +1 @@
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.** { *; }
-keep class io.flutter.util.** { *; }
-keep class io.flutter.view.** { *; }
-keep class io.flutter.** { *; }
-keep class io.flutter.plugins.** { *; }
-keep class com.jcraft.** { *; } -keep class com.jcraft.** { *; }

View File

@@ -3,3 +3,4 @@ distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
distributionSha256Sum=6001aba9b2204d26fa25a5800bb9382cf3ee01ccb78fe77317b2872336eb2f80

View File

@@ -0,0 +1,6 @@
A Flutter project which provide charts to display Linux server status and tools to manage server.
Especially thanks to dartssh2 & xterm.dart.
* Status chart (CPU, Sensors, GPU...), SSH Term, SFTP, Docker & Pkg & Process...
* Platform specific: Bio auth、Msg push、Home widget、watchOS App...
* English, 简体中文; Deutsch, 繁體中文, Indonesian, Français, Dutch; Español, Русский язык, Português, 日本語

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 135 KiB

View File

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 115 KiB

View File

Before

Width:  |  Height:  |  Size: 173 KiB

After

Width:  |  Height:  |  Size: 173 KiB

View File

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 135 KiB

View File

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 135 KiB

View File

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 144 KiB

View File

@@ -0,0 +1 @@
A server status & toolbox app using Flutter

View File

@@ -0,0 +1 @@
ServerBox

View File

@@ -0,0 +1,7 @@
使用 Flutter 开发的 Linux 服务器工具箱,提供服务器状态图表和管理工具。
特别感谢 dartssh2 & xterm.dart。
特点:
* 状态图表CPU、传感器、GPU 等), SSH 终端, SFTP, Docker & 包 & 进程管理器...
* 特殊支持生物认证、推送、桌面小部件、watchOS App、跟随系统颜色...
* 本地化 (English, 简体中文, Español, Русский язык, Português, 日本語, Deutsch, 繁體中文, Indonesian, Français, Dutch

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

View File

@@ -0,0 +1 @@
使用 Flutter 开发的服务器状态和工具箱应用

View File

@@ -0,0 +1 @@
ServerBox

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 112 KiB

View File

@@ -1,6 +1,4 @@
PODS: PODS:
- countly_flutter (24.4.1):
- Flutter
- device_info_plus (0.0.1): - device_info_plus (0.0.1):
- Flutter - Flutter
- file_picker (0.0.1): - file_picker (0.0.1):
@@ -36,7 +34,6 @@ PODS:
- Flutter - Flutter
DEPENDENCIES: DEPENDENCIES:
- countly_flutter (from `.symlinks/plugins/countly_flutter/ios`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`) - file_picker (from `.symlinks/plugins/file_picker/ios`)
- Flutter (from `Flutter`) - Flutter (from `Flutter`)
@@ -55,8 +52,6 @@ DEPENDENCIES:
- watch_connectivity (from `.symlinks/plugins/watch_connectivity/ios`) - watch_connectivity (from `.symlinks/plugins/watch_connectivity/ios`)
EXTERNAL SOURCES: EXTERNAL SOURCES:
countly_flutter:
:path: ".symlinks/plugins/countly_flutter/ios"
device_info_plus: device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios" :path: ".symlinks/plugins/device_info_plus/ios"
file_picker: file_picker:
@@ -91,7 +86,6 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/watch_connectivity/ios" :path: ".symlinks/plugins/watch_connectivity/ios"
SPEC CHECKSUMS: SPEC CHECKSUMS:
countly_flutter: 56233d921c6b4e0a720774a39b8ee8110d6f8d91
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
file_picker: c79185e70b9b45728cde2a8d8da454e0cb43f287 file_picker: c79185e70b9b45728cde2a8d8da454e0cb43f287
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7

View File

@@ -690,7 +690,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 923; CURRENT_PROJECT_VERSION = 1034;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -700,7 +700,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.923; MARKETING_VERSION = 1.0.1034;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -826,7 +826,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 923; CURRENT_PROJECT_VERSION = 1034;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -836,7 +836,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.923; MARKETING_VERSION = 1.0.1034;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -854,7 +854,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 923; CURRENT_PROJECT_VERSION = 1034;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -864,7 +864,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.923; MARKETING_VERSION = 1.0.1034;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -885,7 +885,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 923; CURRENT_PROJECT_VERSION = 1034;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -898,7 +898,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.923; MARKETING_VERSION = 1.0.1034;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
@@ -924,7 +924,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 923; CURRENT_PROJECT_VERSION = 1034;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -937,7 +937,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.923; MARKETING_VERSION = 1.0.1034;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@@ -960,7 +960,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 923; CURRENT_PROJECT_VERSION = 1034;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -973,7 +973,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.923; MARKETING_VERSION = 1.0.1034;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@@ -996,7 +996,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 923; CURRENT_PROJECT_VERSION = 1034;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -1008,7 +1008,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.923; MARKETING_VERSION = 1.0.1034;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
@@ -1037,7 +1037,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 923; CURRENT_PROJECT_VERSION = 1034;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -1049,7 +1049,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.923; MARKETING_VERSION = 1.0.1034;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
PRODUCT_NAME = ServerBox; PRODUCT_NAME = ServerBox;
@@ -1075,7 +1075,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 923; CURRENT_PROJECT_VERSION = 1034;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -1087,7 +1087,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.923; MARKETING_VERSION = 1.0.1034;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
PRODUCT_NAME = ServerBox; PRODUCT_NAME = ServerBox;

View File

@@ -3,10 +3,15 @@ import 'package:fl_lib/fl_lib.dart';
import 'package:fl_lib/l10n/gen_l10n/lib_l10n.dart'; import 'package:fl_lib/l10n/gen_l10n/lib_l10n.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/data/res/build_data.dart'; import 'package:locale_names/locale_names.dart';
import 'package:toolbox/data/res/rebuild.dart'; import 'package:server_box/core/extension/context/locale.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:server_box/data/res/build_data.dart';
import 'package:toolbox/view/page/home/home.dart'; import 'package:server_box/data/res/rebuild.dart';
import 'package:server_box/data/res/store.dart';
import 'package:server_box/view/page/home/home.dart';
import 'package:icons_plus/icons_plus.dart';
part 'intro.dart';
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
const MyApp({super.key}); const MyApp({super.key});
@@ -15,11 +20,22 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
_setup(context); _setup(context);
return ListenableBuilder( return ListenableBuilder(
listenable: RebuildNodes.app, listenable: RNodes.app,
builder: (context, _) { builder: (context, _) {
if (!Stores.setting.useSystemPrimaryColor.fetch()) { if (!Stores.setting.useSystemPrimaryColor.fetch()) {
UIs.colorSeed = Color(Stores.setting.primaryColor.fetch()); UIs.colorSeed = Color(Stores.setting.primaryColor.fetch());
return _buildApp(context); return _buildApp(
context,
light: ThemeData(
useMaterial3: true,
colorSchemeSeed: UIs.colorSeed,
),
dark: ThemeData(
useMaterial3: true,
brightness: Brightness.dark,
colorSchemeSeed: UIs.colorSeed,
),
);
} }
return DynamicColorBuilder( return DynamicColorBuilder(
builder: (light, dark) { builder: (light, dark) {
@@ -32,10 +48,10 @@ class MyApp extends StatelessWidget {
brightness: Brightness.dark, brightness: Brightness.dark,
colorScheme: dark, colorScheme: dark,
); );
if (context.isDark && light != null) { if (context.isDark && dark != null) {
UIs.primaryColor = light.primary;
} else if (!context.isDark && dark != null) {
UIs.primaryColor = dark.primary; UIs.primaryColor = dark.primary;
} else if (!context.isDark && light != null) {
UIs.primaryColor = light.primary;
} }
return _buildApp(context, light: lightTheme, dark: darkTheme); return _buildApp(context, light: lightTheme, dark: darkTheme);
}, },
@@ -44,7 +60,8 @@ class MyApp extends StatelessWidget {
); );
} }
Widget _buildApp(BuildContext ctx, {ThemeData? light, ThemeData? dark}) { Widget _buildApp(BuildContext ctx,
{required ThemeData light, required ThemeData dark}) {
final tMode = Stores.setting.themeMode.fetch(); final tMode = Stores.setting.themeMode.fetch();
// Issue #57 // Issue #57
final themeMode = switch (tMode) { final themeMode = switch (tMode) {
@@ -54,16 +71,6 @@ class MyApp extends StatelessWidget {
}; };
final locale = Stores.setting.locale.fetch().toLocale; final locale = Stores.setting.locale.fetch().toLocale;
light ??= ThemeData(
useMaterial3: true,
colorSchemeSeed: UIs.colorSeed,
);
dark ??= ThemeData(
useMaterial3: true,
brightness: Brightness.dark,
colorSchemeSeed: UIs.colorSeed,
);
return MaterialApp( return MaterialApp(
locale: locale, locale: locale,
localizationsDelegates: const [ localizationsDelegates: const [
@@ -71,17 +78,27 @@ class MyApp extends StatelessWidget {
...AppLocalizations.localizationsDelegates, ...AppLocalizations.localizationsDelegates,
], ],
supportedLocales: AppLocalizations.supportedLocales, supportedLocales: AppLocalizations.supportedLocales,
localeListResolutionCallback: LocaleUtil.resolve,
navigatorObservers: [AppRouteObserver.instance],
title: BuildData.name, title: BuildData.name,
themeMode: themeMode, themeMode: themeMode,
theme: light, theme: light.fixWindowsFont,
darkTheme: tMode < 3 ? dark : dark.toAmoled, darkTheme: (tMode < 3 ? dark : dark.toAmoled).fixWindowsFont,
home: _buildAppContent(ctx), home: Builder(
); builder: (context) {
} context.setLibL10n();
final appL10n = AppLocalizations.of(context);
if (appL10n != null) l10n = appL10n;
Widget _buildAppContent(BuildContext ctx) { final intros = _IntroPage.builders;
//if (Pros.app.isWearOS) return const WearHome(); if (intros.isNotEmpty) {
return const HomePage(); return _IntroPage(intros);
}
return const HomePage();
},
),
);
} }
} }

View File

@@ -1,5 +1,5 @@
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:toolbox/data/res/misc.dart'; import 'package:server_box/data/res/misc.dart';
abstract final class BgRunMC { abstract final class BgRunMC {
static const _channel = MethodChannel('${Miscs.pkgName}/app_retain'); static const _channel = MethodChannel('${Miscs.pkgName}/app_retain');

View File

@@ -1,6 +1,6 @@
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:toolbox/data/res/misc.dart'; import 'package:server_box/data/res/misc.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:server_box/data/res/store.dart';
abstract final class HomeWidgetMC { abstract final class HomeWidgetMC {
static const _channel = MethodChannel('${Miscs.pkgName}/home_widget'); static const _channel = MethodChannel('${Miscs.pkgName}/home_widget');

View File

@@ -1,4 +1,4 @@
import 'package:toolbox/data/res/build_data.dart'; import 'package:server_box/data/res/build_data.dart';
extension BuildDataX on BuildData { extension BuildDataX on BuildData {
static const versionStr = 'v1.0.${BuildData.build}'; static const versionStr = 'v1.0.${BuildData.build}';

View File

@@ -1,4 +1,5 @@
import 'package:dartssh2/dartssh2.dart'; import 'package:dartssh2/dartssh2.dart';
import 'package:server_box/view/widget/unix_perm.dart';
extension SftpFileX on SftpFileMode { extension SftpFileX on SftpFileMode {
String get str { String get str {
@@ -8,6 +9,26 @@ extension SftpFileX on SftpFileMode {
return '$user$group$other'; return '$user$group$other';
} }
UnixPerm toUnixPerm() {
return UnixPerm(
user: RWX(
r: userRead,
w: userWrite,
x: userExecute,
),
group: RWX(
r: groupRead,
w: groupWrite,
x: groupExecute,
),
other: RWX(
r: otherRead,
w: otherWrite,
x: otherExecute,
),
);
}
} }
String _getRoleMode(bool r, bool w, bool x) { String _getRoleMode(bool r, bool w, bool x) {

View File

@@ -1,27 +1,27 @@
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:toolbox/data/model/server/private_key_info.dart'; import 'package:server_box/data/model/server/private_key_info.dart';
import 'package:toolbox/data/model/server/server_private_info.dart'; import 'package:server_box/data/model/server/server_private_info.dart';
import 'package:toolbox/data/res/build_data.dart'; import 'package:server_box/data/res/build_data.dart';
import 'package:toolbox/data/res/provider.dart'; import 'package:server_box/data/res/provider.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:server_box/data/res/store.dart';
import 'package:toolbox/view/page/backup.dart'; import 'package:server_box/view/page/backup.dart';
import 'package:toolbox/view/page/container.dart'; import 'package:server_box/view/page/container.dart';
import 'package:toolbox/view/page/home/home.dart'; import 'package:server_box/view/page/home/home.dart';
import 'package:toolbox/view/page/iperf.dart'; import 'package:server_box/view/page/iperf.dart';
import 'package:toolbox/view/page/ping.dart'; import 'package:server_box/view/page/ping.dart';
import 'package:toolbox/view/page/private_key/edit.dart'; import 'package:server_box/view/page/private_key/edit.dart';
import 'package:toolbox/view/page/private_key/list.dart'; import 'package:server_box/view/page/private_key/list.dart';
import 'package:toolbox/view/page/pve.dart'; import 'package:server_box/view/page/pve.dart';
import 'package:toolbox/view/page/server/detail/view.dart'; import 'package:server_box/view/page/server/detail/view.dart';
import 'package:toolbox/view/page/setting/platform/android.dart'; import 'package:server_box/view/page/setting/platform/android.dart';
import 'package:toolbox/view/page/setting/platform/ios.dart'; import 'package:server_box/view/page/setting/platform/ios.dart';
import 'package:toolbox/view/page/setting/seq/srv_func_seq.dart'; import 'package:server_box/view/page/setting/seq/srv_func_seq.dart';
import 'package:toolbox/view/page/snippet/result.dart'; import 'package:server_box/view/page/snippet/result.dart';
import 'package:toolbox/view/page/ssh/page.dart'; import 'package:server_box/view/page/ssh/page.dart';
import 'package:toolbox/view/page/setting/seq/virt_key.dart'; import 'package:server_box/view/page/setting/seq/virt_key.dart';
import 'package:toolbox/view/page/storage/local.dart'; import 'package:server_box/view/page/storage/local.dart';
import '../data/model/server/snippet.dart'; import '../data/model/server/snippet.dart';
import '../view/page/editor.dart'; import '../view/page/editor.dart';
@@ -102,12 +102,14 @@ class AppRoutes {
Key? key, Key? key,
required ServerPrivateInfo spi, required ServerPrivateInfo spi,
String? initCmd, String? initCmd,
Snippet? initSnippet,
}) { }) {
return AppRoutes( return AppRoutes(
SSHPage( SSHPage(
key: key, key: key,
spi: spi, spi: spi,
initCmd: initCmd, initCmd: initCmd,
initSnippet: initSnippet,
), ),
'ssh_term', 'ssh_term',
); );
@@ -248,6 +250,9 @@ class AppRoutes {
} }
static AppRoutes kvEditor({Key? key, required Map<String, String> data}) { static AppRoutes kvEditor({Key? key, required Map<String, String> data}) {
return AppRoutes(KvEditor(key: key, data: data), 'kv_editor'); return AppRoutes(
KvEditor(key: key, args: KvEditorArgs(data: data)),
'kv_editor',
);
} }
} }

View File

@@ -2,14 +2,9 @@ import 'package:fl_lib/fl_lib.dart';
import 'package:plain_notification_token/plain_notification_token.dart'; import 'package:plain_notification_token/plain_notification_token.dart';
Future<String?> getToken() async { Future<String?> getToken() async {
if (isIOS) { if (!isIOS) return null;
final plainNotificationToken = PlainNotificationToken(); final instance = ApnsToken()..requestPermission();
plainNotificationToken.requestPermission(); // Wait until Permission dialog closed
await instance.onIosSettingsRegistered.first;
// If you want to wait until Permission dialog close, return await instance.getToken();
// you need wait changing setting registered.
await plainNotificationToken.onIosSettingsRegistered.first;
return await plainNotificationToken.getToken();
}
return null;
} }

View File

@@ -2,8 +2,8 @@ import 'dart:async';
import 'package:dartssh2/dartssh2.dart'; import 'package:dartssh2/dartssh2.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:toolbox/data/model/app/error.dart'; import 'package:server_box/data/model/app/error.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:server_box/data/res/store.dart';
import '../../data/model/server/server_private_info.dart'; import '../../data/model/server/server_private_info.dart';

View File

@@ -2,9 +2,9 @@ import 'dart:async';
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:server_box/core/extension/context/locale.dart';
import 'package:toolbox/data/model/server/server_private_info.dart'; import 'package:server_box/data/model/server/server_private_info.dart';
import 'package:toolbox/data/res/provider.dart'; import 'package:server_box/data/res/provider.dart';
abstract final class KeybordInteractive { abstract final class KeybordInteractive {
static FutureOr<List<String>?> defaultHandle( static FutureOr<List<String>?> defaultHandle(

View File

@@ -5,9 +5,9 @@ import 'package:computer/computer.dart';
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:icloud_storage/icloud_storage.dart'; import 'package:icloud_storage/icloud_storage.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:toolbox/data/model/app/backup.dart'; import 'package:server_box/data/model/app/backup.dart';
import 'package:toolbox/data/model/app/sync.dart'; import 'package:server_box/data/model/app/sync.dart';
import 'package:toolbox/data/res/misc.dart'; import 'package:server_box/data/res/misc.dart';
import '../../../data/model/app/error.dart'; import '../../../data/model/app/error.dart';

View File

@@ -3,10 +3,10 @@ import 'dart:io';
import 'package:computer/computer.dart'; import 'package:computer/computer.dart';
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:toolbox/data/model/app/backup.dart'; import 'package:server_box/data/model/app/backup.dart';
import 'package:toolbox/data/model/app/error.dart'; import 'package:server_box/data/model/app/error.dart';
import 'package:toolbox/data/res/misc.dart'; import 'package:server_box/data/res/misc.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:server_box/data/res/store.dart';
import 'package:webdav_client/webdav_client.dart'; import 'package:webdav_client/webdav_client.dart';
abstract final class Webdav { abstract final class Webdav {

View File

@@ -3,13 +3,13 @@ import 'dart:io';
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:toolbox/data/model/server/private_key_info.dart'; import 'package:server_box/data/model/server/private_key_info.dart';
import 'package:toolbox/data/model/server/server_private_info.dart'; import 'package:server_box/data/model/server/server_private_info.dart';
import 'package:toolbox/data/model/server/snippet.dart'; import 'package:server_box/data/model/server/snippet.dart';
import 'package:toolbox/data/res/misc.dart'; import 'package:server_box/data/res/misc.dart';
import 'package:toolbox/data/res/provider.dart'; import 'package:server_box/data/res/provider.dart';
import 'package:toolbox/data/res/rebuild.dart'; import 'package:server_box/data/res/rebuild.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:server_box/data/res/store.dart';
const backupFormatVersion = 1; const backupFormatVersion = 1;
@@ -170,7 +170,7 @@ class Backup {
} }
Pros.reload(); Pros.reload();
RebuildNodes.app.rebuild(); RNodes.app.notify();
_logger.info('Restore success'); _logger.info('Restore success');
} }

View File

@@ -1,4 +1,4 @@
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:server_box/core/extension/context/locale.dart';
enum ErrFrom { enum ErrFrom {
unknown, unknown,

View File

@@ -1,5 +0,0 @@
typedef GhId = String;
extension GhIdX on GhId {
String get url => 'https://github.com/$this';
}

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:server_box/core/extension/context/locale.dart';
enum ContainerMenu { enum ContainerMenu {
start, start,

View File

@@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
import 'package:icons_plus/icons_plus.dart'; import 'package:icons_plus/icons_plus.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:server_box/core/extension/context/locale.dart';
part 'server_func.g.dart'; part 'server_func.g.dart';
@@ -15,8 +15,8 @@ enum ServerFuncBtn {
container, container,
@HiveField(3) @HiveField(3)
process, process,
@HiveField(4) //@HiveField(4)
pkg, //pkg,
@HiveField(5) @HiveField(5)
snippet, snippet,
@HiveField(6) @HiveField(6)
@@ -30,14 +30,14 @@ enum ServerFuncBtn {
sftp, sftp,
container, container,
process, process,
pkg, //pkg,
snippet, snippet,
].map((e) => e.index).toList(); ].map((e) => e.index).toList();
IconData get icon => switch (this) { IconData get icon => switch (this) {
sftp => Icons.insert_drive_file, sftp => Icons.insert_drive_file,
snippet => Icons.code, snippet => Icons.code,
pkg => Icons.system_security_update, //pkg => Icons.system_security_update,
container => FontAwesome.docker_brand, container => FontAwesome.docker_brand,
process => Icons.list_alt_outlined, process => Icons.list_alt_outlined,
terminal => Icons.terminal, terminal => Icons.terminal,
@@ -47,7 +47,7 @@ enum ServerFuncBtn {
String get toStr => switch (this) { String get toStr => switch (this) {
sftp => 'SFTP', sftp => 'SFTP',
snippet => l10n.snippet, snippet => l10n.snippet,
pkg => l10n.pkg, //pkg => l10n.pkg,
container => l10n.container, container => l10n.container,
process => l10n.process, process => l10n.process,
terminal => l10n.terminal, terminal => l10n.terminal,

View File

@@ -21,8 +21,6 @@ class ServerFuncBtnAdapter extends TypeAdapter<ServerFuncBtn> {
return ServerFuncBtn.container; return ServerFuncBtn.container;
case 3: case 3:
return ServerFuncBtn.process; return ServerFuncBtn.process;
case 4:
return ServerFuncBtn.pkg;
case 5: case 5:
return ServerFuncBtn.snippet; return ServerFuncBtn.snippet;
case 6: case 6:
@@ -47,9 +45,6 @@ class ServerFuncBtnAdapter extends TypeAdapter<ServerFuncBtn> {
case ServerFuncBtn.process: case ServerFuncBtn.process:
writer.writeByte(3); writer.writeByte(3);
break; break;
case ServerFuncBtn.pkg:
writer.writeByte(4);
break;
case ServerFuncBtn.snippet: case ServerFuncBtn.snippet:
writer.writeByte(5); writer.writeByte(5);
break; break;

View File

@@ -1,7 +1,7 @@
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:server_box/core/extension/context/locale.dart';
import 'package:toolbox/data/model/server/server.dart'; import 'package:server_box/data/model/server/server.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:server_box/data/res/store.dart';
part 'net_view.g.dart'; part 'net_view.g.dart';

View File

@@ -1,23 +0,0 @@
import 'package:flutter/foundation.dart';
class RebuildNode implements Listenable {
final List<VoidCallback> _listeners = [];
RebuildNode();
@override
void addListener(VoidCallback listener) {
_listeners.add(listener);
}
@override
void removeListener(VoidCallback listener) {
_listeners.remove(listener);
}
void rebuild() {
for (var listener in _listeners) {
listener();
}
}
}

View File

@@ -1,8 +1,8 @@
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:icons_plus/icons_plus.dart'; import 'package:icons_plus/icons_plus.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:server_box/core/extension/context/locale.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:server_box/data/res/store.dart';
enum ServerDetailCards { enum ServerDetailCards {
about(Icons.info), about(Icons.info),

View File

@@ -1,4 +1,4 @@
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:server_box/core/extension/context/locale.dart';
import '../../res/build_data.dart'; import '../../res/build_data.dart';
import '../server/system.dart'; import '../server/system.dart';
@@ -12,52 +12,32 @@ enum ShellFunc {
suspend, suspend,
; ;
static const _homeVar = '\$HOME';
static const seperator = 'SrvBoxSep'; static const seperator = 'SrvBoxSep';
/// The suffix `\t` is for formatting /// The suffix `\t` is for formatting
static const cmdDivider = '\necho $seperator\n\t'; static const cmdDivider = '\necho $seperator\n\t';
static const _srvBoxDir = '.config/server_box';
static const scriptFile = 'mobile_v${BuildData.script}.sh';
/// Issue #159 /// srvboxm -> ServerBox Mobile
/// static const scriptFile = 'srvboxm_v${BuildData.script}.sh';
/// Use script commit count as version of shell script. static const scriptDir = '~/.config/server_box';
/// static const scriptPath = '$scriptDir/$scriptFile';
/// So different version of app can run at the same time.
///
/// **Can't** use it in SFTP, because SFTP can't recognize `$HOME`
static String getShellPath(String home) => '$home/$_srvBoxDir/$scriptFile';
static const srvBoxDir = '$_homeVar/$_srvBoxDir'; static const String installShellCmd = """
static const _installShellPath = '$_homeVar/$_srvBoxDir/$scriptFile'; mkdir -p $scriptDir
cat > $scriptPath
// Issue #299, chmod ~/.config to avoid permission issue chmod 744 $scriptPath
static const installShellCmd = """
chmod +x ~/.config &> /dev/null
mkdir -p $_homeVar/$_srvBoxDir
cat > $_installShellPath
chmod +x $_installShellPath
"""; """;
String get flag { String get flag => switch (this) {
switch (this) { ShellFunc.process => 'p',
case ShellFunc.status: ShellFunc.shutdown => 'sd',
return 's'; ShellFunc.reboot => 'r',
// case ShellFunc.docker: ShellFunc.suspend => 'sp',
// return 'd'; ShellFunc.status => 's',
case ShellFunc.process: // ShellFunc.docker=> 'd',
return 'p'; };
case ShellFunc.shutdown:
return 'sd';
case ShellFunc.reboot:
return 'r';
case ShellFunc.suspend:
return 'sp';
}
}
String get exec => 'sh $_installShellPath -$flag'; String get exec => 'sh $scriptPath -$flag';
String get name { String get name {
switch (this) { switch (this) {
@@ -213,6 +193,7 @@ enum StatusCmdType {
'for f in /sys/class/power_supply/*/uevent; do cat "\$f"; echo; done'), 'for f in /sys/class/power_supply/*/uevent; do cat "\$f"; echo; done'),
nvidia._('nvidia-smi -q -x'), nvidia._('nvidia-smi -q -x'),
sensors._('sensors'), sensors._('sensors'),
cpuBrand._('cat /proc/cpuinfo | grep "model name"'),
; ;
final String cmd; final String cmd;
@@ -231,6 +212,7 @@ enum BSDStatusCmdType {
mem._('top -l 1 | grep PhysMem'), mem._('top -l 1 | grep PhysMem'),
//temp, //temp,
host._('hostname'), host._('hostname'),
cpuBrand._('sysctl -n machdep.cpu.brand_string'),
; ;
final String cmd; final String cmd;

View File

@@ -1,8 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:toolbox/view/page/ping.dart'; import 'package:server_box/view/page/ping.dart';
import 'package:toolbox/view/page/server/tab.dart'; import 'package:server_box/view/page/server/tab.dart';
import 'package:toolbox/view/page/snippet/list.dart'; import 'package:server_box/view/page/snippet/list.dart';
import 'package:toolbox/view/page/ssh/tab.dart'; import 'package:server_box/view/page/ssh/tab.dart';
enum AppTab { enum AppTab {
server, server,

View File

@@ -1,7 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:toolbox/data/model/container/type.dart'; import 'package:server_box/data/model/container/type.dart';
abstract final class ContainerImg { abstract final class ContainerImg {
final String? repository = null; final String? repository = null;
@@ -72,7 +72,7 @@ final class DockerImg implements ContainerImg {
final String repository; final String repository;
final String size; final String size;
@override @override
final String tag; final String? tag;
DockerImg({ DockerImg({
required this.containers, required this.containers,
@@ -95,14 +95,30 @@ final class DockerImg implements ContainerImg {
String toRawJson() => json.encode(toJson()); String toRawJson() => json.encode(toJson());
factory DockerImg.fromJson(Map<String, dynamic> json) => DockerImg( factory DockerImg.fromJson(Map<String, dynamic> json) {
containers: json["Containers"], final containers = switch (json["Containers"]) {
createdAt: json["CreatedAt"], final String a => a,
id: json["ID"], final Object? a => a.toString(),
repository: json["Repository"], };
size: json["Size"], final repo = switch (json["Repository"] ?? json["Names"]) {
tag: json["Tag"], final String a => a,
); final List a => a.firstOrNull.toString(),
final Object? a => a.toString(),
};
final size = switch (json["Size"]) {
final String a => a,
final int a => a.bytes2Str,
final Object? a => a.toString(),
};
return DockerImg(
containers: containers,
createdAt: json["CreatedAt"],
id: json["ID"] ?? json["Id"] ?? '',
repository: repo,
size: size,
tag: json["Tag"],
);
}
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"Containers": containers, "Containers": containers,

View File

@@ -1,10 +1,11 @@
import 'dart:convert'; import 'dart:convert';
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:server_box/core/extension/context/locale.dart';
import 'package:toolbox/data/model/container/type.dart'; import 'package:server_box/data/model/container/type.dart';
import 'package:server_box/data/res/misc.dart';
abstract final class ContainerPs { sealed class ContainerPs {
final String? id = null; final String? id = null;
final String? image = null; final String? image = null;
String? get name; String? get name;
@@ -140,7 +141,10 @@ final class DockerPs implements ContainerPs {
String? get cmd => null; String? get cmd => null;
@override @override
bool get running => state?.contains('Up ') ?? false; bool get running {
if (state?.contains('Exited') == true) return false;
return true;
}
@override @override
void parseStats(String s) { void parseStats(String s) {
@@ -154,12 +158,12 @@ final class DockerPs implements ContainerPs {
/// CONTAINER ID NAMES IMAGE STATUS /// CONTAINER ID NAMES IMAGE STATUS
/// a049d689e7a1 aria2-pro p3terx/aria2-pro Up 3 weeks /// a049d689e7a1 aria2-pro p3terx/aria2-pro Up 3 weeks
factory DockerPs.parse(String raw) { factory DockerPs.parse(String raw) {
final parts = raw.split(RegExp(r'\s{2,}')); final parts = raw.split(Miscs.multiBlankreg);
return DockerPs( return DockerPs(
id: parts[0], id: parts[0],
names: parts[1], state: parts[1],
image: parts[2], names: parts[2],
state: parts[3], image: parts[3].trim(),
); );
} }
} }

View File

@@ -1,5 +1,5 @@
import 'package:toolbox/data/model/container/image.dart'; import 'package:server_box/data/model/container/image.dart';
import 'package:toolbox/data/model/container/ps.dart'; import 'package:server_box/data/model/container/ps.dart';
enum ContainerType { enum ContainerType {
docker, docker,

View File

@@ -1,4 +1,4 @@
import 'package:toolbox/data/model/server/dist.dart'; import 'package:server_box/data/model/server/dist.dart';
enum PkgManager { enum PkgManager {
apt, apt,

View File

@@ -1,4 +1,4 @@
import 'package:toolbox/data/model/pkg/manager.dart'; import 'package:server_box/data/model/pkg/manager.dart';
class UpgradePkgInfo { class UpgradePkgInfo {
final PkgManager? _mgr; final PkgManager? _mgr;

View File

@@ -1,14 +1,16 @@
import 'dart:collection';
import 'package:fl_chart/fl_chart.dart'; import 'package:fl_chart/fl_chart.dart';
import 'package:toolbox/data/model/server/time_seq.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:toolbox/data/res/status.dart'; import 'package:server_box/data/model/server/time_seq.dart';
import 'package:server_box/data/res/status.dart';
/// Capacity of the FIFO queue
const _kCap = 30; const _kCap = 30;
class Cpus extends TimeSeq<List<SingleCpuCore>> { class Cpus extends TimeSeq<List<SingleCpuCore>> {
Cpus(super.init1, super.init2); Cpus(super.init1, super.init2);
final Map<String, int> brand = {};
@override @override
void onUpdate() { void onUpdate() {
_coresCount = now.length; _coresCount = now.length;
@@ -23,10 +25,16 @@ class Cpus extends TimeSeq<List<SingleCpuCore>> {
double usedPercent({int coreIdx = 0}) { double usedPercent({int coreIdx = 0}) {
if (now.length != pre.length) return 0; if (now.length != pre.length) return 0;
final idleDelta = now[coreIdx].idle - pre[coreIdx].idle; if (now.isEmpty) return 0;
final totalDelta = now[coreIdx].total - pre[coreIdx].total; try {
final used = idleDelta / totalDelta; final idleDelta = now[coreIdx].idle - pre[coreIdx].idle;
return used.isNaN ? 0 : 100 - used * 100; final totalDelta = now[coreIdx].total - pre[coreIdx].total;
final used = idleDelta / totalDelta;
return used.isNaN ? 0 : 100 - used * 100;
} catch (e, s) {
Loggers.app.warning('Cpus.usedPercent()', e, s);
return 0;
}
} }
int _coresCount = 0; int _coresCount = 0;
@@ -175,6 +183,22 @@ class SingleCpuCore extends TimeSeqIface<SingleCpuCore> {
} }
} }
final class CpuBrand {
static Map<String, int> parse(String raw) {
final lines = raw.split('\n');
// {brand: count}
final brands = <String, int>{};
for (var line in lines) {
if (line.contains('model name')) {
final model = line.split(':').last.trim();
final count = brands[model] ?? 0;
brands[model] = count + 1;
}
}
return brands;
}
}
final _bsdCpuPercentReg = RegExp(r'(\d+\.\d+)%'); final _bsdCpuPercentReg = RegExp(r'(\d+\.\d+)%');
/// TODO: Change this implementation to parse cpu status on BSD system /// TODO: Change this implementation to parse cpu status on BSD system

View File

@@ -1,5 +1,5 @@
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:toolbox/data/model/server/time_seq.dart'; import 'package:server_box/data/model/server/time_seq.dart';
import '../../res/misc.dart'; import '../../res/misc.dart';

View File

@@ -1,5 +1,5 @@
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:server_box/core/extension/context/locale.dart';
enum PveResType { enum PveResType {
lxc, lxc,

View File

@@ -1,5 +1,5 @@
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:server_box/core/extension/context/locale.dart';
final class SensorAdaptor { final class SensorAdaptor {
final String raw; final String raw;

View File

@@ -1,19 +1,19 @@
import 'package:dartssh2/dartssh2.dart'; import 'package:dartssh2/dartssh2.dart';
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:server_box/core/extension/context/locale.dart';
import 'package:toolbox/data/model/app/error.dart'; import 'package:server_box/data/model/app/error.dart';
import 'package:toolbox/data/model/app/shell_func.dart'; import 'package:server_box/data/model/app/shell_func.dart';
import 'package:toolbox/data/model/server/battery.dart'; import 'package:server_box/data/model/server/battery.dart';
import 'package:toolbox/data/model/server/conn.dart'; import 'package:server_box/data/model/server/conn.dart';
import 'package:toolbox/data/model/server/cpu.dart'; import 'package:server_box/data/model/server/cpu.dart';
import 'package:toolbox/data/model/server/disk.dart'; import 'package:server_box/data/model/server/disk.dart';
import 'package:toolbox/data/model/server/memory.dart'; import 'package:server_box/data/model/server/memory.dart';
import 'package:toolbox/data/model/server/net_speed.dart'; import 'package:server_box/data/model/server/net_speed.dart';
import 'package:toolbox/data/model/server/nvdia.dart'; import 'package:server_box/data/model/server/nvdia.dart';
import 'package:toolbox/data/model/server/sensors.dart'; import 'package:server_box/data/model/server/sensors.dart';
import 'package:toolbox/data/model/server/server_private_info.dart'; import 'package:server_box/data/model/server/server_private_info.dart';
import 'package:toolbox/data/model/server/system.dart'; import 'package:server_box/data/model/server/system.dart';
import 'package:toolbox/data/model/server/temp.dart'; import 'package:server_box/data/model/server/temp.dart';
import '../app/tag_pickable.dart'; import '../app/tag_pickable.dart';

View File

@@ -1,8 +1,8 @@
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
import 'package:toolbox/data/model/server/custom.dart'; import 'package:server_box/data/model/server/custom.dart';
import 'package:toolbox/data/model/server/server.dart'; import 'package:server_box/data/model/server/server.dart';
import 'package:toolbox/data/model/server/wol_cfg.dart'; import 'package:server_box/data/model/server/wol_cfg.dart';
import 'package:toolbox/data/res/provider.dart'; import 'package:server_box/data/res/provider.dart';
import '../app/error.dart'; import '../app/error.dart';
@@ -42,6 +42,10 @@ class ServerPrivateInfo {
@HiveField(11) @HiveField(11)
final WakeOnLanCfg? wolCfg; final WakeOnLanCfg? wolCfg;
/// It only applies to SSH terminal.
@HiveField(12)
final Map<String, String>? envs;
final String id; final String id;
const ServerPrivateInfo({ const ServerPrivateInfo({
@@ -57,6 +61,7 @@ class ServerPrivateInfo {
this.jumpId, this.jumpId,
this.custom, this.custom,
this.wolCfg, this.wolCfg,
this.envs,
}) : id = '$user@$ip:$port'; }) : id = '$user@$ip:$port';
static ServerPrivateInfo fromJson(Map<String, dynamic> json) { static ServerPrivateInfo fromJson(Map<String, dynamic> json) {
@@ -76,6 +81,15 @@ class ServerPrivateInfo {
final wolCfg = json["wolCfg"] == null final wolCfg = json["wolCfg"] == null
? null ? null
: WakeOnLanCfg.fromJson(json["wolCfg"].cast<String, dynamic>()); : WakeOnLanCfg.fromJson(json["wolCfg"].cast<String, dynamic>());
final envs_ = json["envs"] as Map<String, dynamic>?;
final envs = <String, String>{};
if (envs_ != null) {
envs_.forEach((key, value) {
if (value is String) {
envs[key] = value;
}
});
}
return ServerPrivateInfo( return ServerPrivateInfo(
name: name, name: name,
@@ -90,6 +104,7 @@ class ServerPrivateInfo {
jumpId: jumpId, jumpId: jumpId,
custom: custom, custom: custom,
wolCfg: wolCfg, wolCfg: wolCfg,
envs: envs.isEmpty ? null : envs,
); );
} }
@@ -123,6 +138,9 @@ class ServerPrivateInfo {
if (wolCfg != null) { if (wolCfg != null) {
data["wolCfg"] = wolCfg?.toJson(); data["wolCfg"] = wolCfg?.toJson();
} }
if (envs != null) {
data["envs"] = envs;
}
return data; return data;
} }

View File

@@ -29,13 +29,14 @@ class ServerPrivateInfoAdapter extends TypeAdapter<ServerPrivateInfo> {
jumpId: fields[9] as String?, jumpId: fields[9] as String?,
custom: fields[10] as ServerCustom?, custom: fields[10] as ServerCustom?,
wolCfg: fields[11] as WakeOnLanCfg?, wolCfg: fields[11] as WakeOnLanCfg?,
envs: (fields[12] as Map?)?.cast<String, String>(),
); );
} }
@override @override
void write(BinaryWriter writer, ServerPrivateInfo obj) { void write(BinaryWriter writer, ServerPrivateInfo obj) {
writer writer
..writeByte(12) ..writeByte(13)
..writeByte(0) ..writeByte(0)
..write(obj.name) ..write(obj.name)
..writeByte(1) ..writeByte(1)
@@ -59,7 +60,9 @@ class ServerPrivateInfoAdapter extends TypeAdapter<ServerPrivateInfo> {
..writeByte(10) ..writeByte(10)
..write(obj.custom) ..write(obj.custom)
..writeByte(11) ..writeByte(11)
..write(obj.wolCfg); ..write(obj.wolCfg)
..writeByte(12)
..write(obj.envs);
} }
@override @override

View File

@@ -1,9 +1,9 @@
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:toolbox/data/model/server/battery.dart'; import 'package:server_box/data/model/server/battery.dart';
import 'package:toolbox/data/model/server/nvdia.dart'; import 'package:server_box/data/model/server/nvdia.dart';
import 'package:toolbox/data/model/server/sensors.dart'; import 'package:server_box/data/model/server/sensors.dart';
import 'package:toolbox/data/model/server/server.dart'; import 'package:server_box/data/model/server/server.dart';
import 'package:toolbox/data/model/server/system.dart'; import 'package:server_box/data/model/server/system.dart';
import '../app/shell_func.dart'; import '../app/shell_func.dart';
import 'cpu.dart'; import 'cpu.dart';
@@ -71,6 +71,9 @@ Future<ServerStatus> _getLinuxStatus(ServerStatusUpdateReq req) async {
try { try {
final cpus = SingleCpuCore.parse(StatusCmdType.cpu.find(segments)); final cpus = SingleCpuCore.parse(StatusCmdType.cpu.find(segments));
req.ss.cpu.update(cpus); req.ss.cpu.update(cpus);
final brand = CpuBrand.parse(StatusCmdType.cpuBrand.find(segments));
req.ss.cpu.brand.clear();
req.ss.cpu.brand.addAll(brand);
} catch (e, s) { } catch (e, s) {
Loggers.app.warning(e, s); Loggers.app.warning(e, s);
} }

View File

@@ -1,5 +1,9 @@
import 'dart:async';
import 'package:fl_lib/fl_lib.dart';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
import 'package:toolbox/data/model/server/server_private_info.dart'; import 'package:server_box/data/model/server/server_private_info.dart';
import 'package:xterm/core.dart';
import '../app/tag_pickable.dart'; import '../app/tag_pickable.dart';
@@ -53,19 +57,116 @@ class Snippet implements TagPickable {
@override @override
String get tagName => name; String get tagName => name;
String fmtWith(ServerPrivateInfo spi) { static final fmtFinder = RegExp(r'\$\{[^{}]+\}');
final fmted = script.replaceAllMapped(
RegExp(r'\${.+?}'), String fmtWithSpi(ServerPrivateInfo spi) {
return script.replaceAllMapped(
fmtFinder,
(match) { (match) {
final key = match.group(0); final key = match.group(0);
final func = fmtArgs[key]; final func = fmtArgs[key];
if (func == null) { if (func != null) return func(spi);
return key!; // If not found, return the original content for further processing
} return key ?? '';
return func(spi);
}, },
); );
return fmted; }
Future<void> runInTerm(
Terminal terminal,
ServerPrivateInfo spi, {
bool autoEnter = false,
}) async {
final argsFmted = fmtWithSpi(spi);
final matches = fmtFinder.allMatches(argsFmted);
/// There is no [TerminalKey] in the script
if (matches.isEmpty) {
terminal.textInput(argsFmted);
if (autoEnter) terminal.keyInput(TerminalKey.enter);
return;
}
// Records all start and end indexes of the matches
final (starts, ends) = matches.fold((<int>[], <int>[]), (pre, e) {
pre.$1.add(e.start);
pre.$2.add(e.end);
return pre;
});
// Check all indexes, `(idx + 1).start` must >= `idx.end`
for (var i = 0; i < starts.length - 1; i++) {
final lastEnd = ends[i];
final nextStart = starts[i + 1];
if (nextStart < lastEnd) {
throw 'Invalid format: $nextStart < $lastEnd';
}
}
// Start term input
if (starts.first > 0) {
terminal.textInput(argsFmted.substring(0, starts.first));
}
// Process matched
for (var idx = 0; idx < starts.length; idx++) {
final start = starts[idx];
final end = ends[idx];
final key = argsFmted.substring(start, end).toLowerCase();
// Special funcs
final special = _find(SnippetFuncs.specialCtrl, key);
if (special != null) {
final raw = key.substring(special.key.length + 1, key.length - 1);
await special.value((term: terminal, raw: raw));
}
// Term keys
final termKey = _find(fmtTermKeys, key);
if (termKey != null) await _doTermKeys(terminal, termKey, key);
}
// End term input
if (ends.last < argsFmted.length) {
terminal.textInput(argsFmted.substring(ends.last));
}
if (autoEnter) terminal.keyInput(TerminalKey.enter);
}
Future<void> _doTermKeys(
Terminal terminal,
MapEntry<String, TerminalKey> termKey,
String key,
) async {
if (termKey.value == TerminalKey.enter) {
terminal.keyInput(TerminalKey.enter);
return;
}
final ctrlAlt = switch (termKey.value) {
TerminalKey.control => (ctrl: true, alt: false),
TerminalKey.alt => (ctrl: false, alt: true),
_ => (ctrl: false, alt: false),
};
// `${ctrl+ad}` -> `ctrla + d`
final chars = key.substring(termKey.key.length + 1, key.length - 1);
if (chars.isEmpty) return;
final ok = terminal.charInput(
chars.codeUnitAt(0),
ctrl: ctrlAlt.ctrl,
alt: ctrlAlt.alt,
);
if (!ok) {
Loggers.app.warning('Failed to input: $key');
}
terminal.textInput(chars.substring(1));
}
MapEntry<String, T>? _find<T>(Map<String, T> map, String key) {
return map.entries.firstWhereOrNull((e) => key.startsWith(e.key));
} }
static final fmtArgs = { static final fmtArgs = {
@@ -76,6 +177,12 @@ class Snippet implements TagPickable {
r'${id}': (ServerPrivateInfo spi) => spi.id, r'${id}': (ServerPrivateInfo spi) => spi.id,
r'${name}': (ServerPrivateInfo spi) => spi.name, r'${name}': (ServerPrivateInfo spi) => spi.name,
}; };
/// r'${ctrl+ad}' -> TerminalKey.control, a, d
static final fmtTermKeys = {
r'${ctrl': TerminalKey.control,
r'${alt': TerminalKey.alt,
};
} }
class SnippetResult { class SnippetResult {
@@ -89,3 +196,32 @@ class SnippetResult {
required this.time, required this.time,
}); });
} }
typedef SnippetFuncCtx = ({Terminal term, String raw});
abstract final class SnippetFuncs {
static final specialCtrl = {
// `${sleep 3}` -> sleep 3 seconds
r'${sleep': SnippetFuncs.sleep,
r'${enter': SnippetFuncs.enter,
};
static const help = {
'sleep': 'Sleep for a few seconds',
'enter': 'Enter a few times',
};
static FutureOr<void> sleep(SnippetFuncCtx ctx) async {
final seconds = int.tryParse(ctx.raw);
if (seconds == null) return;
final duration = Duration(seconds: seconds);
await Future.delayed(duration);
}
static FutureOr<void> enter(SnippetFuncCtx ctx) async {
final times = int.tryParse(ctx.raw) ?? 1;
for (var i = 0; i < times; i++) {
ctx.term.keyInput(TerminalKey.enter);
}
}
}

View File

@@ -1,4 +1,4 @@
import 'package:toolbox/data/model/app/shell_func.dart'; import 'package:server_box/data/model/app/shell_func.dart';
enum SystemType { enum SystemType {
linux._(linuxSign), linux._(linuxSign),

View File

@@ -1,4 +1,4 @@
import 'package:toolbox/data/res/store.dart'; import 'package:server_box/data/res/store.dart';
class TryLimiter { class TryLimiter {
final Map<String, int> _triedTimes = {}; final Map<String, int> _triedTimes = {};

View File

@@ -1,5 +1,5 @@
import 'package:dartssh2/dartssh2.dart'; import 'package:dartssh2/dartssh2.dart';
import 'package:toolbox/data/model/sftp/absolute_path.dart'; import 'package:server_box/data/model/sftp/absolute_path.dart';
class SftpBrowserStatus { class SftpBrowserStatus {
List<SftpName>? files; List<SftpName>? files;

View File

@@ -1,7 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:server_box/data/res/store.dart';
import '../../../core/utils/server.dart'; import '../../../core/utils/server.dart';
import '../server/server_private_info.dart'; import '../server/server_private_info.dart';

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:server_box/core/extension/context/locale.dart';
import 'package:xterm/core.dart'; import 'package:xterm/core.dart';
part 'virtual_key.g.dart'; part 'virtual_key.g.dart';

View File

@@ -3,13 +3,6 @@ import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AppProvider extends ChangeNotifier { class AppProvider extends ChangeNotifier {
int? _newestBuild;
int? get newestBuild => _newestBuild;
set newestBuild(int? build) {
_newestBuild = build;
notifyListeners();
}
BuildContext? ctx; BuildContext? ctx;
bool isWearOS = false; bool isWearOS = false;

View File

@@ -4,13 +4,13 @@ import 'dart:convert';
import 'package:dartssh2/dartssh2.dart'; import 'package:dartssh2/dartssh2.dart';
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:toolbox/core/extension/ssh_client.dart'; import 'package:server_box/core/extension/ssh_client.dart';
import 'package:toolbox/data/model/app/shell_func.dart'; import 'package:server_box/data/model/app/shell_func.dart';
import 'package:toolbox/data/model/container/image.dart'; import 'package:server_box/data/model/container/image.dart';
import 'package:toolbox/data/model/container/ps.dart'; import 'package:server_box/data/model/container/ps.dart';
import 'package:toolbox/data/model/app/error.dart'; import 'package:server_box/data/model/app/error.dart';
import 'package:toolbox/data/model/container/type.dart'; import 'package:server_box/data/model/container/type.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:server_box/data/res/store.dart';
final _dockerNotFound = final _dockerNotFound =
RegExp(r"command not found|Unknown command|Command '\w+' not found"); RegExp(r"command not found|Unknown command|Command '\w+' not found");
@@ -160,11 +160,18 @@ class ContainerProvider extends ChangeNotifier {
} }
// Parse images // Parse images
final imageRaw = ContainerCmdType.images.find(segments); final imageRaw = ContainerCmdType.images.find(segments).trim();
final isEntireJson = imageRaw.startsWith('[') && imageRaw.endsWith(']');
try { try {
final imgLines = imageRaw.split('\n'); if (isEntireJson) {
imgLines.removeWhere((element) => element.isEmpty); images = (json.decode(imageRaw) as List)
images = imgLines.map((e) => ContainerImg.fromRawJson(e, type)).toList(); .map((e) => ContainerImg.fromRawJson(json.encode(e), type))
.toList();
} else {
final lines = imageRaw.split('\n');
lines.removeWhere((element) => element.isEmpty);
images = lines.map((e) => ContainerImg.fromRawJson(e, type)).toList();
}
} catch (e, trace) { } catch (e, trace) {
error = ContainerErr( error = ContainerErr(
type: ContainerErrType.parseImages, type: ContainerErrType.parseImages,
@@ -276,9 +283,13 @@ enum ContainerCmdType {
return switch (this) { return switch (this) {
ContainerCmdType.version => '$prefix version $_jsonFmt', ContainerCmdType.version => '$prefix version $_jsonFmt',
ContainerCmdType.ps => switch (type) { ContainerCmdType.ps => switch (type) {
/// TODO: Rollback to json format when permformance recovers.
/// Use [_jsonFmt] in Docker will cause the operation to slow down. /// Use [_jsonFmt] in Docker will cause the operation to slow down.
ContainerType.docker => '$prefix ps -a --format "table ' ContainerType.docker => '$prefix ps -a --format "table {{printf \\"'
'{{printf \\"${"%-30.30s " * 4}\\" .ID .Names .Image .Status}}"', '%-15.15s '
'%-30.30s '
'${"%-50.50s " * 2}\\"'
' .ID .Status .Names .Image}}"',
ContainerType.podman => '$prefix ps -a $_jsonFmt', ContainerType.podman => '$prefix ps -a $_jsonFmt',
}, },
ContainerCmdType.stats => ContainerCmdType.stats =>
@@ -294,6 +305,6 @@ enum ContainerCmdType {
}) { }) {
return ContainerCmdType.values return ContainerCmdType.values
.map((e) => e.exec(type, sudo: sudo, includeStats: includeStats)) .map((e) => e.exec(type, sudo: sudo, includeStats: includeStats))
.join(' && echo ${ShellFunc.seperator} && '); .join('\necho ${ShellFunc.seperator}\n');
} }
} }

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:toolbox/data/model/server/private_key_info.dart'; import 'package:server_box/data/model/server/private_key_info.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:server_box/data/res/store.dart';
class PrivateKeyProvider extends ChangeNotifier { class PrivateKeyProvider extends ChangeNotifier {
List<PrivateKeyInfo> get pkis => _pkis; List<PrivateKeyInfo> get pkis => _pkis;

View File

@@ -6,10 +6,10 @@ import 'package:dio/dio.dart';
import 'package:dio/io.dart'; import 'package:dio/io.dart';
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:server_box/core/extension/context/locale.dart';
import 'package:toolbox/data/model/app/error.dart'; import 'package:server_box/data/model/app/error.dart';
import 'package:toolbox/data/model/server/pve.dart'; import 'package:server_box/data/model/server/pve.dart';
import 'package:toolbox/data/model/server/server_private_info.dart'; import 'package:server_box/data/model/server/server_private_info.dart';
import 'package:dartssh2/dartssh2.dart'; import 'package:dartssh2/dartssh2.dart';
typedef PveCtrlFunc = Future<bool> Function(String node, String id); typedef PveCtrlFunc = Future<bool> Function(String node, String id);

View File

@@ -1,24 +1,23 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; // import 'dart:io';
import 'package:computer/computer.dart'; import 'package:computer/computer.dart';
import 'package:dartssh2/dartssh2.dart'; import 'package:dartssh2/dartssh2.dart';
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:toolbox/core/extension/ssh_client.dart'; import 'package:server_box/core/extension/ssh_client.dart';
import 'package:toolbox/core/utils/ssh_auth.dart'; import 'package:server_box/core/utils/ssh_auth.dart';
import 'package:toolbox/data/model/app/error.dart'; import 'package:server_box/data/model/app/error.dart';
import 'package:toolbox/data/model/app/shell_func.dart'; import 'package:server_box/data/model/app/shell_func.dart';
import 'package:toolbox/data/model/server/system.dart'; import 'package:server_box/data/model/server/system.dart';
import 'package:toolbox/data/model/sftp/req.dart'; // import 'package:server_box/data/model/sftp/req.dart';
import 'package:toolbox/data/res/provider.dart'; // import 'package:server_box/data/res/provider.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:server_box/data/res/store.dart';
import '../../core/utils/server.dart'; import '../../core/utils/server.dart';
import '../model/server/server.dart'; import '../model/server/server.dart';
import '../model/server/server_private_info.dart'; import '../model/server/server_private_info.dart';
import '../model/server/server_status_update_req.dart'; import '../model/server/server_status_update_req.dart';
import '../model/server/snippet.dart';
import '../model/server/try_limiter.dart'; import '../model/server/try_limiter.dart';
import '../res/status.dart'; import '../res/status.dart';
@@ -314,11 +313,10 @@ class ServerProvider extends ChangeNotifier {
_setServerState(s, ServerConn.connected); _setServerState(s, ServerConn.connected);
// Write script to server
// by ssh
final scriptRaw = ShellFunc.allScript(spi.custom?.cmds).uint8List; final scriptRaw = ShellFunc.allScript(spi.custom?.cmds).uint8List;
try { try {
await s.client?.runForOutput( await s.client!.runForOutput(
ShellFunc.installShellCmd, ShellFunc.installShellCmd,
action: (session) async { action: (session) async {
session.stdin.add(scriptRaw); session.stdin.add(scriptRaw);
@@ -336,40 +334,11 @@ class ServerProvider extends ChangeNotifier {
_setServerState(s, ServerConn.failed); _setServerState(s, ServerConn.failed);
return; return;
} catch (e) { } catch (e) {
Loggers.app.warning('Write script to ${spi.name} by shell', e); final err = e.toString();
TryLimiter.inc(sid);
/// by sftp s.status.err = SSHErr(type: SSHErrType.writeScript, message: err);
final localPath = Paths.doc.joinPath('install.sh'); _setServerState(s, ServerConn.failed);
final file = File(localPath); Loggers.app.warning('Write script to ${spi.name} by shell', err);
try {
file.writeAsBytes(scriptRaw);
final completer = Completer();
final homePath = (await s.client?.run('echo \$HOME').string)?.trim();
if (homePath == null || homePath.isEmpty) {
throw Exception('Got empty home path');
}
final remotePath = ShellFunc.getShellPath(homePath);
final reqId = Pros.sftp.add(
SftpReq(spi, remotePath, localPath, SftpReqType.upload),
completer: completer,
);
await completer.future;
final err = Pros.sftp.get(reqId)?.error;
if (err != null) {
throw err;
}
} catch (ee) {
TryLimiter.inc(sid);
s.status.err = SSHErr(
type: SSHErrType.writeScript,
message: '$e\n\n$ee',
);
_setServerState(s, ServerConn.failed);
Loggers.app.warning('Write script to ${spi.name} by sftp', ee);
return;
} finally {
if (await file.exists()) await file.delete();
}
} }
} }
@@ -459,26 +428,4 @@ class ServerProvider extends ChangeNotifier {
// reset try times only after prepared successfully // reset try times only after prepared successfully
TryLimiter.reset(sid); TryLimiter.reset(sid);
} }
Future<SnippetResult?> runSnippet(String id, Snippet snippet) async {
final server = _servers[id];
if (server == null) return null;
final watch = Stopwatch()..start();
final result = await server.client?.run(snippet.fmtWith(server.spi)).string;
final time = watch.elapsed;
watch.stop();
if (result == null) return null;
return SnippetResult(
dest: _servers[id]?.spi.name,
result: result,
time: time,
);
}
// Future<List<SnippetResult?>> runSnippetsMulti(
// List<String> ids,
// Snippet snippet,
// ) async {
// return await Future.wait(ids.map((id) async => runSnippet(id, snippet)));
// }
} }

View File

@@ -2,8 +2,8 @@ import 'dart:convert';
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:toolbox/data/model/server/snippet.dart'; import 'package:server_box/data/model/server/snippet.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:server_box/data/res/store.dart';
class SnippetProvider extends ChangeNotifier { class SnippetProvider extends ChangeNotifier {
late List<Snippet> _snippets; late List<Snippet> _snippets;

View File

@@ -1,5 +1,5 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:server_box/data/res/store.dart';
import 'package:xterm/core.dart'; import 'package:xterm/core.dart';
class VirtKeyProvider extends TerminalInputHandler with ChangeNotifier { class VirtKeyProvider extends TerminalInputHandler with ChangeNotifier {

View File

@@ -2,9 +2,6 @@
class BuildData { class BuildData {
static const String name = "ServerBox"; static const String name = "ServerBox";
static const int build = 923; static const int build = 1034;
static const String engine = "3.22.1"; static const int script = 54;
static const String buildAt = "2024-06-01 22:31:14";
static const int modifications = 4;
static const int script = 48;
} }

View File

@@ -1,25 +1,27 @@
import 'package:toolbox/data/model/app/github_id.dart';
abstract final class GithubIds { abstract final class GithubIds {
// Thanks // Thanks
// If you want to change your Github ID, please open an issue. // If you want to change your Github ID, please open an issue.
static const contributors = <GhId>{ static const contributors = <GhId>{
'PaperCube', 'PaperCube',
'Integral-Tech',
'its-tom', 'its-tom',
'leganck',
'azkadev', 'azkadev',
'kalashnikov', 'kalashnikov',
'FrancXPT',
'RainSunMe',
'calvinweb', 'calvinweb',
'No06',
'QazCetelic',
'RainSunMe',
'FrancXPT',
'Liloupar', 'Liloupar',
'dccif', 'dccif',
'QazCetelic',
}; };
static const participants = <GhId>{ static const participants = <GhId>{
'jaychoubaby', 'jaychoubaby',
'fecture', 'fecture',
'Tao173', 'Tao173',
'Jasonzhu1207',
'QingAnLe', 'QingAnLe',
'wxdjs', 'wxdjs',
'Aeorq', 'Aeorq',
@@ -72,6 +74,32 @@ abstract final class GithubIds {
'pgs666', 'pgs666',
'FHU-yezi', 'FHU-yezi',
'ZRY233', 'ZRY233',
'Jasonzhu1207', 'sakuraanzu',
'licaon-kter',
'77160860',
'mijjjj',
'muyunil',
'Hua159',
'jaydong2016',
'geol',
'Mooling0602',
'IllTamer',
'marlkiller',
'hlarc',
'itsandrewpao',
'StudyingLover',
'QJAG1024',
'Wuming-HUST',
'WolfCanglong',
'liwenjie119',
'logce',
'h-lyf',
'88484396',
}; };
} }
typedef GhId = String;
extension GhIdX on GhId {
String get url => 'https://github.com/$this';
}

View File

@@ -2,6 +2,7 @@ import 'dart:convert';
abstract final class Miscs { abstract final class Miscs {
static final blankReg = RegExp(r'\s+'); static final blankReg = RegExp(r'\s+');
static final multiBlankreg = RegExp(r'\s{2,}');
/// RegExp for password request /// RegExp for password request
static final pwdRequestWithUserReg = RegExp(r'\[sudo\] password for (.+):'); static final pwdRequestWithUserReg = RegExp(r'\[sudo\] password for (.+):');

View File

@@ -1,9 +1,9 @@
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:toolbox/data/provider/app.dart'; import 'package:server_box/data/provider/app.dart';
import 'package:toolbox/data/provider/private_key.dart'; import 'package:server_box/data/provider/private_key.dart';
import 'package:toolbox/data/provider/server.dart'; import 'package:server_box/data/provider/server.dart';
import 'package:toolbox/data/provider/sftp.dart'; import 'package:server_box/data/provider/sftp.dart';
import 'package:toolbox/data/provider/snippet.dart'; import 'package:server_box/data/provider/snippet.dart';
abstract final class Pros { abstract final class Pros {
static final app = AppProvider(); static final app = AppProvider();

View File

@@ -1,5 +1,6 @@
import 'package:toolbox/data/model/app/rebuild.dart'; import 'package:fl_lib/fl_lib.dart';
abstract final class RebuildNodes { abstract final class RNodes {
static final app = RebuildNode(); static final app = RNode();
static final dark = false.vn;
} }

View File

@@ -1,5 +1,5 @@
import 'package:toolbox/data/model/server/server.dart'; import 'package:server_box/data/model/server/server.dart';
import 'package:toolbox/data/model/server/temp.dart'; import 'package:server_box/data/model/server/temp.dart';
import '../model/server/cpu.dart'; import '../model/server/cpu.dart';
import '../model/server/disk.dart'; import '../model/server/disk.dart';

View File

@@ -1,10 +1,10 @@
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:toolbox/data/store/container.dart'; import 'package:server_box/data/store/container.dart';
import 'package:toolbox/data/store/history.dart'; import 'package:server_box/data/store/history.dart';
import 'package:toolbox/data/store/private_key.dart'; import 'package:server_box/data/store/private_key.dart';
import 'package:toolbox/data/store/server.dart'; import 'package:server_box/data/store/server.dart';
import 'package:toolbox/data/store/setting.dart'; import 'package:server_box/data/store/setting.dart';
import 'package:toolbox/data/store/snippet.dart'; import 'package:server_box/data/store/snippet.dart';
abstract final class Stores { abstract final class Stores {
static final setting = SettingStore(); static final setting = SettingStore();

View File

@@ -1,8 +1,9 @@
abstract final class Urls { abstract final class Urls {
static const cdnBase = 'https://cdn.lolli.tech/serverbox'; static const cdnBase = 'https://cdn.lolli.tech/serverbox';
static const updateCfg = '$cdnBase/update.json'; static const updateCfg = '$cdnBase/update2.json';
static const myGithub = 'https://github.com/lollipopkit'; static const myGithub = 'https://github.com/lollipopkit';
static const appHelp = '$myGithub/flutter_server_box#-help'; static const thisRepo = '$myGithub/flutter_server_box';
static const appWiki = '$myGithub/flutter_server_box/wiki'; static const appHelp = '$thisRepo#-help';
static const appWiki = '$thisRepo/wiki';
static const analysis = 'https://countly.lolli.tech'; static const analysis = 'https://countly.lolli.tech';
} }

View File

@@ -1,6 +1,6 @@
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:toolbox/data/model/container/type.dart'; import 'package:server_box/data/model/container/type.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:server_box/data/res/store.dart';
const _keyConfig = 'providerConfig'; const _keyConfig = 'providerConfig';

View File

@@ -54,4 +54,7 @@ class HistoryStore extends PersistentStore {
late final sftpLastPath = _MapHistory(box: box, name: 'sftpLastPath'); late final sftpLastPath = _MapHistory(box: box, name: 'sftpLastPath');
late final sshCmds = _ListHistory(box: box, name: 'sshCmds'); late final sshCmds = _ListHistory(box: box, name: 'sshCmds');
/// Notify users that this app will write script to server to works properly
late final writeScriptTipShown = property('writeScriptTipShown', false);
} }

View File

@@ -1,7 +1,7 @@
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:toolbox/data/model/app/menu/server_func.dart'; import 'package:server_box/data/model/app/menu/server_func.dart';
import 'package:toolbox/data/model/app/server_detail_card.dart'; import 'package:server_box/data/model/app/server_detail_card.dart';
import 'package:toolbox/data/model/ssh/virtual_key.dart'; import 'package:server_box/data/model/ssh/virtual_key.dart';
import '../model/app/net_view.dart'; import '../model/app/net_view.dart';
import '../res/default.dart'; import '../res/default.dart';
@@ -265,8 +265,6 @@ class SettingStore extends PersistentStore {
late final horizonVirtKey = property('horizonVirtKey', false); late final horizonVirtKey = property('horizonVirtKey', false);
late final collectUsage = property('collectUsage', true);
/// general wake lock /// general wake lock
late final generalWakeLock = property('generalWakeLock', false); late final generalWakeLock = property('generalWakeLock', false);
@@ -276,6 +274,20 @@ class SettingStore extends PersistentStore {
/// fmt: https://example.com/{DIST}-{BRIGHT}.png /// fmt: https://example.com/{DIST}-{BRIGHT}.png
late final serverLogoUrl = property('serverLogoUrl', ''); late final serverLogoUrl = property('serverLogoUrl', '');
late final betaTest = property('betaTest', false);
/// If it's empty, skip change window size.
/// Format: {width}x{height}
late final windowSize = property('windowSize', '');
late final introVer = property('introVer', 0);
late final letterCache = property('letterCache', false);
/// Set it to `$EDITOR`, `vim` and etc. to use remote system editor in SSH terminal.
/// Set it empty to use local editor GUI.
late final sftpEditor = property('sftpEditor', '');
// Never show these settings for users // Never show these settings for users
// //
// ------BEGIN------ // ------BEGIN------

129
lib/intro.dart Normal file
View File

@@ -0,0 +1,129 @@
part of 'app.dart';
final class _IntroPage extends StatelessWidget {
final List<IntroPageBuilder> pages;
const _IntroPage(this.pages);
static const _builders = {
1: _buildAppSettings,
2: _buildRecommended,
1006: _buildTermLetterCache,
};
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, cons) {
final padTop = cons.maxHeight * .16;
final pages_ = pages.map((e) => e(context, padTop)).toList();
return IntroPage(
args: IntroPageArgs(
pages: pages_,
onDone: (ctx) {
Stores.setting.introVer.put(BuildData.build);
Navigator.of(ctx).pushReplacement(
MaterialPageRoute(builder: (_) => const HomePage()),
);
},
),
);
},
);
}
static Widget _buildTermLetterCache(BuildContext context, double padTop) {
return ListView(
padding: _introListPad,
children: [
SizedBox(height: padTop),
IntroPage.title(icon: BoxIcons.bxs_terminal, big: true),
SizedBox(height: padTop),
ListTile(
leading: const Icon(Bootstrap.alphabet),
title: Text(l10n.letterCache),
subtitle: Text(l10n.letterCacheTip, style: UIs.textGrey),
trailing: StoreSwitch(prop: _setting.letterCache),
).cardx,
],
);
}
static Widget _buildRecommended(BuildContext context, double padTop) {
return ListView(
padding: _introListPad,
children: [
SizedBox(height: padTop),
IntroPage.title(icon: Bootstrap.stars, big: true),
SizedBox(height: padTop),
ListTile(
leading: const Icon(MingCute.delete_2_fill),
title: const Text('rm -r'),
subtitle: Text(l10n.sftpRmrDirSummary, style: UIs.textGrey),
trailing: StoreSwitch(prop: _setting.sftpRmrDir),
).cardx,
ListTile(
leading: const Icon(MingCute.chart_line_line, size: _kIconSize),
title: Text(l10n.stat),
subtitle: Text(l10n.parseContainerStatsTip, style: UIs.textGrey),
trailing: StoreSwitch(prop: _setting.containerParseStat),
).cardx,
ListTile(
leading: const Icon(OctIcons.cpu),
title: Text(l10n.noLineChartForCpu),
subtitle: Text(l10n.cpuViewAsProgressTip, style: UIs.textGrey),
trailing: StoreSwitch(prop: _setting.cpuViewAsProgress),
).cardx,
],
);
}
static Widget _buildAppSettings(BuildContext ctx, double padTop) {
return ListView(
padding: _introListPad,
children: [
SizedBox(height: padTop),
IntroPage.title(text: l10n.init, big: true),
SizedBox(height: padTop),
ListTile(
leading: const Icon(IonIcons.language),
title: Text(l10n.language),
onTap: () async {
final selected = await ctx.showPickSingleDialog(
title: l10n.language,
items: AppLocalizations.supportedLocales,
name: (p0) => '${p0.nativeDisplayLanguage} (${p0.code})',
initial: _setting.locale.fetch().toLocale,
);
if (selected != null) {
_setting.locale.put(selected.code);
RNodes.app.notify();
}
},
trailing: Text(
l10n.languageName,
style: const TextStyle(fontSize: 15, color: Colors.grey),
),
).cardx,
ListTile(
leading: const Icon(Icons.update),
title: Text(l10n.autoCheckUpdate),
subtitle: Text(l10n.fdroidReleaseTip, style: UIs.textGrey),
trailing: StoreSwitch(prop: _setting.autoCheckAppUpdate),
).cardx,
],
);
}
static List<IntroPageBuilder> get builders {
final storedVer = _setting.introVer.fetch();
return _builders.entries
.where((e) => e.key > storedVer)
.map((e) => e.value)
.toList();
}
static final _setting = Stores.setting;
static const _kIconSize = 23.0;
static const _introListPad = EdgeInsets.symmetric(horizontal: 17);
}

View File

@@ -2,6 +2,7 @@
"@@locale": "de", "@@locale": "de",
"about": "Über", "about": "Über",
"aboutThanks": "Vielen Dank an die folgenden Personen, die daran teilgenommen haben.\n", "aboutThanks": "Vielen Dank an die folgenden Personen, die daran teilgenommen haben.\n",
"acceptBeta": "Akzeptieren Sie Testversion-Updates",
"add": "Neu", "add": "Neu",
"addAServer": "Server hinzufügen", "addAServer": "Server hinzufügen",
"addPrivateKey": "Private key hinzufügen", "addPrivateKey": "Private key hinzufügen",
@@ -10,7 +11,6 @@
"addr": "Adresse", "addr": "Adresse",
"all": "Alle", "all": "Alle",
"alreadyLastDir": "Bereits im letzten Verzeichnis.", "alreadyLastDir": "Bereits im letzten Verzeichnis.",
"alterUrl": "Url ändern",
"askContinue": "{msg}. Weiter?", "askContinue": "{msg}. Weiter?",
"attention": "Achtung", "attention": "Achtung",
"authFailTip": "Authentifizierung fehlgeschlagen, bitte überprüfen Sie, ob das Passwort/Schlüssel/Host/Benutzer usw. falsch sind.", "authFailTip": "Authentifizierung fehlgeschlagen, bitte überprüfen Sie, ob das Passwort/Schlüssel/Host/Benutzer usw. falsch sind.",
@@ -44,7 +44,6 @@
"cnKeyboardCompTip": "Wenn das Terminal ein sicheres Tastenfeld öffnet, können Sie es aktivieren.", "cnKeyboardCompTip": "Wenn das Terminal ein sicheres Tastenfeld öffnet, können Sie es aktivieren.",
"collapseUI": "Zusammenbrechen", "collapseUI": "Zusammenbrechen",
"collapseUITip": "Ob lange Listen in der Benutzeroberfläche standardmäßig eingeklappt werden sollen oder nicht", "collapseUITip": "Ob lange Listen in der Benutzeroberfläche standardmäßig eingeklappt werden sollen oder nicht",
"collectUsage": "Nutzungsinformationen sammeln (unabhängig von der Privatsphäre).",
"conn": "Verbindung", "conn": "Verbindung",
"connected": "in Verbindung gebracht", "connected": "in Verbindung gebracht",
"container": "Container", "container": "Container",
@@ -68,7 +67,6 @@
"decode": "Decode", "decode": "Decode",
"decompress": "Dekomprimieren", "decompress": "Dekomprimieren",
"delete": "Löschen", "delete": "Löschen",
"deleteScripts": "Gleichzeitiges Löschen von Server-Skripten",
"deleteServers": "Batch-Löschung von Servern", "deleteServers": "Batch-Löschung von Servern",
"deviceName": "Gerätename", "deviceName": "Gerätename",
"dirEmpty": "Stelle sicher, dass der Ordner leer ist.", "dirEmpty": "Stelle sicher, dass der Ordner leer ist.",
@@ -94,12 +92,15 @@
"editor": "Editor", "editor": "Editor",
"editorHighlightTip": "Die Leistung der aktuellen Codehervorhebung ist schlechter und kann zur Verbesserung optional ausgeschaltet werden.", "editorHighlightTip": "Die Leistung der aktuellen Codehervorhebung ist schlechter und kann zur Verbesserung optional ausgeschaltet werden.",
"encode": "Encode", "encode": "Encode",
"envVars": "Umgebungsvariable",
"error": "Fehler", "error": "Fehler",
"exampleName": "Servername", "exampleName": "Servername",
"experimentalFeature": "Experimentelles Feature", "experimentalFeature": "Experimentelles Feature",
"export": "Export", "export": "Export",
"extraArgs": "Extra args", "extraArgs": "Extra args",
"failed": "Failed", "failed": "Failed",
"fallbackSshDest": "SSH-Fallback-Ziel",
"fdroidReleaseTip": "Wenn Sie diese App von F-Droid heruntergeladen haben, wird empfohlen, diese Option zu deaktivieren.",
"feedback": "Feedback", "feedback": "Feedback",
"feedbackOnGithub": "Wenn du Fragen hast, stelle diese bitte auf Github.", "feedbackOnGithub": "Wenn du Fragen hast, stelle diese bitte auf Github.",
"fieldMustNotEmpty": "Die Eingabefelder dürfen nicht leer sein.", "fieldMustNotEmpty": "Die Eingabefelder dürfen nicht leer sein.",
@@ -110,6 +111,7 @@
"followSystem": "System verfolgen", "followSystem": "System verfolgen",
"font": "Schriftarten", "font": "Schriftarten",
"fontSize": "Schriftgröße", "fontSize": "Schriftgröße",
"forExample": "Zum Beispiel",
"force": "freiwillig", "force": "freiwillig",
"foundNUpdate": "Update {count} gefunden", "foundNUpdate": "Update {count} gefunden",
"fullScreen": "Vollbildmodus", "fullScreen": "Vollbildmodus",
@@ -133,6 +135,7 @@
"imagesList": "Images", "imagesList": "Images",
"import": "Importieren", "import": "Importieren",
"inAppUpdate": "Im App aktualisieren? Andernfalls mit einem Browser herunterladen.", "inAppUpdate": "Im App aktualisieren? Andernfalls mit einem Browser herunterladen.",
"init": "Initialisieren",
"inner": "Eingebaut", "inner": "Eingebaut",
"inputDomainHere": "Domain eingeben", "inputDomainHere": "Domain eingeben",
"install": "install", "install": "install",
@@ -151,6 +154,8 @@
"languageName": "Deutsch", "languageName": "Deutsch",
"lastTry": "Letzter Versuch", "lastTry": "Letzter Versuch",
"launchPage": "Startseite", "launchPage": "Startseite",
"letterCache": "Buchstaben-Caching",
"letterCacheTip": "Empfohlen, zu deaktivieren, aber nach dem Deaktivieren können keine CJK-Zeichen eingegeben werden.",
"license": "Lizenzen", "license": "Lizenzen",
"light": "Hell", "light": "Hell",
"loadingFiles": "Lädt Dateien...", "loadingFiles": "Lädt Dateien...",
@@ -171,12 +176,13 @@
"name": "Name", "name": "Name",
"needHomeDir": "Wenn Sie ein Synology-Benutzer sind, [sehen Sie hier](https://kb.synology.com/DSM/tutorial/user_enable_home_service). Benutzer anderer Systeme müssen suchen, wie man ein Home-Verzeichnis erstellt.", "needHomeDir": "Wenn Sie ein Synology-Benutzer sind, [sehen Sie hier](https://kb.synology.com/DSM/tutorial/user_enable_home_service). Benutzer anderer Systeme müssen suchen, wie man ein Home-Verzeichnis erstellt.",
"needRestart": "App muss neugestartet werden", "needRestart": "App muss neugestartet werden",
"net": "Netz", "net": "Netzwerk",
"netViewType": "Netzwerkansicht Typ", "netViewType": "Netzwerkansicht Typ",
"newContainer": "Neuer Container", "newContainer": "Neuer Container",
"noClient": "Kein Client", "noClient": "Kein Client",
"noInterface": "Kein Interface", "noInterface": "Kein Interface",
"noLineChart": "Verwenden Sie keine Liniendiagramme", "noLineChart": "Verwenden Sie keine Liniendiagramme",
"noLineChartForCpu": "Verwenden Sie keine Liniendiagramme für CPU",
"noNotiPerm": "Keine Benachrichtigungsrechte, möglicherweise keine Fortschrittsanzeige beim Herunterladen von App-Updates.", "noNotiPerm": "Keine Benachrichtigungsrechte, möglicherweise keine Fortschrittsanzeige beim Herunterladen von App-Updates.",
"noOptions": "Keine Optionen verfügbar", "noOptions": "Keine Optionen verfügbar",
"noPrivateKeyTip": "Der private Schlüssel existiert nicht, möglicherweise wurde er gelöscht oder es liegt ein Konfigurationsfehler vor.", "noPrivateKeyTip": "Der private Schlüssel existiert nicht, möglicherweise wurde er gelöscht oder es liegt ein Konfigurationsfehler vor.",
@@ -199,11 +205,11 @@
"open": "Öffnen", "open": "Öffnen",
"openLastPath": "Öffnen Sie den letzten Pfad", "openLastPath": "Öffnen Sie den letzten Pfad",
"openLastPathTip": "Verschiedene Server haben unterschiedliche Einträge, und der Eintrag ist der Pfad zum Ausgang", "openLastPathTip": "Verschiedene Server haben unterschiedliche Einträge, und der Eintrag ist der Pfad zum Ausgang",
"parseContainerStats": "Den Status der Container-Belegung analysieren",
"parseContainerStatsTip": "Das Analysieren des Belegungsstatus durch Docker ist relativ langsam", "parseContainerStatsTip": "Das Analysieren des Belegungsstatus durch Docker ist relativ langsam",
"paste": "Einfügen", "paste": "Einfügen",
"path": "Pfad", "path": "Pfad",
"percentOfSize": "{percent}% von {size}", "percentOfSize": "{percent}% von {size}",
"permission": "Berechtigungen",
"pickFile": "Datei wählen", "pickFile": "Datei wählen",
"pingAvg": "Avg:", "pingAvg": "Avg:",
"pingInputIP": "Bitte gib eine Ziel-IP/Domain ein.", "pingInputIP": "Bitte gib eine Ziel-IP/Domain ein.",
@@ -229,6 +235,7 @@
"rememberChoice": "Auswahl merken", "rememberChoice": "Auswahl merken",
"rememberPwdInMem": "Passwort im Speicher behalten", "rememberPwdInMem": "Passwort im Speicher behalten",
"rememberPwdInMemTip": "Für Container, Aufhängen usw.", "rememberPwdInMemTip": "Für Container, Aufhängen usw.",
"rememberWindowSize": "Fenstergröße merken",
"remotePath": "Entfernte Pfade", "remotePath": "Entfernte Pfade",
"rename": "Umbenennen", "rename": "Umbenennen",
"reportBugsOnGithubIssue": "Bitte Bugs auf {url} melden", "reportBugsOnGithubIssue": "Bitte Bugs auf {url} melden",
@@ -257,6 +264,7 @@
"serverTabUnkown": "Unbekannter Status", "serverTabUnkown": "Unbekannter Status",
"setting": "Einstellungen", "setting": "Einstellungen",
"sftpDlPrepare": "Verbindung vorbereiten...", "sftpDlPrepare": "Verbindung vorbereiten...",
"sftpEditorTip": "Wenn leer, verwenden Sie den im App integrierten Dateieditor. Wenn ein Wert vorhanden ist, wird der Editor des Remote-Servers verwendet, z.B. `vim` (es wird empfohlen, automatisch gemäß `EDITOR` zu ermitteln).",
"sftpRmrDirSummary": "Verwenden Sie \"rm -r\", um das Verzeichnis in SFTP zu löschen.", "sftpRmrDirSummary": "Verwenden Sie \"rm -r\", um das Verzeichnis in SFTP zu löschen.",
"sftpSSHConnected": "SFTP Verbunden", "sftpSSHConnected": "SFTP Verbunden",
"sftpShowFoldersFirst": "Ordner zuerst anzeigen", "sftpShowFoldersFirst": "Ordner zuerst anzeigen",
@@ -271,6 +279,7 @@
"sshTip": "Diese Funktion befindet sich jetzt in der Experimentierphase.\n\nBitte melde Bugs auf {url} oder mach mit bei der Entwicklung.", "sshTip": "Diese Funktion befindet sich jetzt in der Experimentierphase.\n\nBitte melde Bugs auf {url} oder mach mit bei der Entwicklung.",
"sshVirtualKeyAutoOff": "Automatische Umschaltung der virtuellen Tasten", "sshVirtualKeyAutoOff": "Automatische Umschaltung der virtuellen Tasten",
"start": "Start", "start": "Start",
"stat": "Statistik",
"stats": "Statistik", "stats": "Statistik",
"stop": "Stop", "stop": "Stop",
"stopped": "Ausgelaufen", "stopped": "Ausgelaufen",
@@ -297,7 +306,7 @@
"total": "Total", "total": "Total",
"traffic": "Durchflussmenge", "traffic": "Durchflussmenge",
"trySudo": "Versuche es mit sudo", "trySudo": "Versuche es mit sudo",
"ttl": "ttl", "ttl": "TTL",
"unknown": "Unbekannt", "unknown": "Unbekannt",
"unknownError": "Unbekannter Fehler", "unknownError": "Unbekannter Fehler",
"unkownConvertMode": "Unbekannter Konvertierungsmodus", "unkownConvertMode": "Unbekannter Konvertierungsmodus",
@@ -333,5 +342,6 @@
"willTakEeffectImmediately": "Wird sofort angewendet", "willTakEeffectImmediately": "Wird sofort angewendet",
"wolTip": "Nach der Konfiguration von WOL (Wake-on-LAN) wird jedes Mal, wenn der Server verbunden wird, eine WOL-Anfrage gesendet.", "wolTip": "Nach der Konfiguration von WOL (Wake-on-LAN) wird jedes Mal, wenn der Server verbunden wird, eine WOL-Anfrage gesendet.",
"write": "Schreiben", "write": "Schreiben",
"writeScriptFailTip": "Das Schreiben des Skripts ist fehlgeschlagen, möglicherweise aufgrund fehlender Berechtigungen oder das Verzeichnis existiert nicht." "writeScriptFailTip": "Das Schreiben des Skripts ist fehlgeschlagen, möglicherweise aufgrund fehlender Berechtigungen oder das Verzeichnis existiert nicht.",
"writeScriptTip": "Nach der Verbindung mit dem Server wird ein Skript in ~/.config/server_box geschrieben, um den Systemstatus zu überwachen. Sie können den Skriptinhalt überprüfen."
} }

View File

@@ -2,31 +2,31 @@
"@@locale": "en", "@@locale": "en",
"about": "About", "about": "About",
"aboutThanks": "Thanks to the following people who participated in.", "aboutThanks": "Thanks to the following people who participated in.",
"acceptBeta": "Accept beta version updates",
"add": "Add", "add": "Add",
"addAServer": "add a server", "addAServer": "add a server",
"addPrivateKey": "Add private key", "addPrivateKey": "Add private key",
"addSystemPrivateKeyTip": "Currently don't have any private key, do you add the one that comes with the system (~/.ssh/id_rsa)?", "addSystemPrivateKeyTip": "Currently private keys don't exist, do you want to add the one that comes with the system (~/.ssh/id_rsa)?",
"added2List": "Added to task list", "added2List": "Added to task list",
"addr": "Address", "addr": "Address",
"all": "All", "all": "All",
"alreadyLastDir": "Already in last directory.", "alreadyLastDir": "Already in last directory.",
"alterUrl": "Alter url",
"askContinue": "{msg}. Continue?", "askContinue": "{msg}. Continue?",
"attention": "Attention", "attention": "Attention",
"authFailTip": "Authentication failed, please check if the password/key/host/user, etc., are incorrect.", "authFailTip": "Authentication failed, please check whether credentials are correct",
"authRequired": "Auth required", "authRequired": "Auth required",
"auto": "Auto", "auto": "Auto",
"autoBackupConflict": "Only one automatic backup can be turned on at the same time.", "autoBackupConflict": "Only one automatic backup can be turned on at the same time.",
"autoCheckUpdate": "Auto check update", "autoCheckUpdate": "Automatic update check",
"autoConnect": "Auto connect", "autoConnect": "Auto connect",
"autoRun": "Automatic Run", "autoRun": "Auto run",
"autoUpdateHomeWidget": "Auto update home widget", "autoUpdateHomeWidget": "Automatic home widget update",
"backup": "Backup", "backup": "Backup",
"backupTip": "The exported data is simply encrypted. \nPlease keep it safe.", "backupTip": "The exported data is weakly encrypted. \nPlease keep it safe.",
"backupVersionNotMatch": "Backup version is not match.", "backupVersionNotMatch": "Backup version is not match.",
"battery": "Battery", "battery": "Battery",
"bgRun": "Run in backgroud", "bgRun": "Run in background",
"bgRunTip": "This switch only means the program will try to run in the background, whether it can run in the background depends on whether the permission is enabled or not. For native Android, please disable \"Battery Optimization\" in this app, and for miui, please change the power saving policy to \"Unlimited\".", "bgRunTip": "This switch only means the program will try to run in the background. Whether it can run in the background depends on whether the permission is enabled or not. For AOSP-based Android ROMs, please disable \"Battery Optimization\" in this app. For MIUI / HyperOS, please change the power saving policy to \"Unlimited\".",
"bioAuth": "Biometric auth", "bioAuth": "Biometric auth",
"browser": "Browser", "browser": "Browser",
"bulkImportServers": "Batch import servers", "bulkImportServers": "Batch import servers",
@@ -44,7 +44,6 @@
"cnKeyboardCompTip": "If the terminal pops up a secure keyboard, you can enable it.", "cnKeyboardCompTip": "If the terminal pops up a secure keyboard, you can enable it.",
"collapseUI": "Collapse", "collapseUI": "Collapse",
"collapseUITip": "Whether to collapse long lists present in the UI by default", "collapseUITip": "Whether to collapse long lists present in the UI by default",
"collectUsage": "Collect usage information (unrelated to privacy).",
"conn": "Connection", "conn": "Connection",
"connected": "Connected", "connected": "Connected",
"container": "Container", "container": "Container",
@@ -55,7 +54,7 @@
"convert": "Convert", "convert": "Convert",
"copy": "Copy", "copy": "Copy",
"copyPath": "Copy path", "copyPath": "Copy path",
"cpuViewAsProgressTip": "Display the usage rate of each CPU in a progress bar style (old style)", "cpuViewAsProgressTip": "Display the usage of each CPU in a progress bar style (old style)",
"createFile": "Create file", "createFile": "Create file",
"createFolder": "Create folder", "createFolder": "Create folder",
"cursorType": "Cursor type", "cursorType": "Cursor type",
@@ -68,10 +67,9 @@
"decode": "Decode", "decode": "Decode",
"decompress": "Decompress", "decompress": "Decompress",
"delete": "Delete", "delete": "Delete",
"deleteScripts": "Delete server scripts at the same time",
"deleteServers": "Batch delete servers", "deleteServers": "Batch delete servers",
"deviceName": "Device name", "deviceName": "Device name",
"dirEmpty": "Make sure dir is empty.", "dirEmpty": "Make sure the folder is empty.",
"disabled": "Disabled", "disabled": "Disabled",
"disconnected": "Disconnected", "disconnected": "Disconnected",
"disk": "Disk", "disk": "Disk",
@@ -92,16 +90,19 @@
"edit": "Edit", "edit": "Edit",
"editVirtKeys": "Edit virtual keys", "editVirtKeys": "Edit virtual keys",
"editor": "Editor", "editor": "Editor",
"editorHighlightTip": "The current code highlighting performance is worse and can be optionally turned off to improve.", "editorHighlightTip": "The current code highlighting performance is not ideal and can be optionally turned off to improve.",
"encode": "Encode", "encode": "Encode",
"envVars": "Environment variable",
"error": "Error", "error": "Error",
"exampleName": "Example name", "exampleName": "Example name",
"experimentalFeature": "Experimental feature", "experimentalFeature": "Experimental feature",
"export": "Export", "export": "Export",
"extraArgs": "Extra args", "extraArgs": "Extra arguments",
"failed": "Failed", "failed": "Failed",
"fallbackSshDest": "Fallback SSH destination",
"fdroidReleaseTip": "If you downloaded this app from F-Droid, it is recommended to turn off this option.",
"feedback": "Feedback", "feedback": "Feedback",
"feedbackOnGithub": "If you have any questions, please feedback on Github.", "feedbackOnGithub": "If you have any questions, please create issues on Github.",
"fieldMustNotEmpty": "These fields must not be empty.", "fieldMustNotEmpty": "These fields must not be empty.",
"fileNotExist": "{file} not exist", "fileNotExist": "{file} not exist",
"fileTooLarge": "File '{file}' too large {size}, max {sizeMax}", "fileTooLarge": "File '{file}' too large {size}, max {sizeMax}",
@@ -110,6 +111,7 @@
"followSystem": "Follow system", "followSystem": "Follow system",
"font": "Font", "font": "Font",
"fontSize": "Font size", "fontSize": "Font size",
"forExample": "For example",
"force": "Force", "force": "Force",
"foundNUpdate": "Found {count} update", "foundNUpdate": "Found {count} update",
"fullScreen": "Full screen mode", "fullScreen": "Full screen mode",
@@ -122,7 +124,7 @@
"goto": "Go to", "goto": "Go to",
"hideTitleBar": "Hide title bar", "hideTitleBar": "Hide title bar",
"hideTitleBarTip": "After turning it on, please hold down the three buttons in the top right corner to drag.", "hideTitleBarTip": "After turning it on, please hold down the three buttons in the top right corner to drag.",
"highlight": "Code highlight", "highlight": "Code highlighting",
"homeWidgetUrlConfig": "Config home widget url", "homeWidgetUrlConfig": "Config home widget url",
"host": "Host", "host": "Host",
"hour": "Hour", "hour": "Hour",
@@ -133,6 +135,7 @@
"imagesList": "Images list", "imagesList": "Images list",
"import": "Import", "import": "Import",
"inAppUpdate": "Update within the app? Otherwise, download using a browser.", "inAppUpdate": "Update within the app? Otherwise, download using a browser.",
"init": "Initialize",
"inner": "Inner", "inner": "Inner",
"inputDomainHere": "Input Domain here", "inputDomainHere": "Input Domain here",
"install": "install", "install": "install",
@@ -151,6 +154,8 @@
"languageName": "English", "languageName": "English",
"lastTry": "Last try", "lastTry": "Last try",
"launchPage": "Launch page", "launchPage": "Launch page",
"letterCache": "Letter caching",
"letterCacheTip": "Recommended to disable, but after disabling, it will be impossible to input CJK characters.",
"license": "License", "license": "License",
"light": "Light", "light": "Light",
"loadingFiles": "Loading files...", "loadingFiles": "Loading files...",
@@ -160,7 +165,7 @@
"madeWithLove": "Made with ❤️ by {myGithub}", "madeWithLove": "Made with ❤️ by {myGithub}",
"manual": "Manual", "manual": "Manual",
"max": "max", "max": "max",
"maxRetryCount": "Number of server reconnection", "maxRetryCount": "Number of server reconnections",
"maxRetryCountEqual0": "Will retry again and again.", "maxRetryCountEqual0": "Will retry again and again.",
"min": "min", "min": "min",
"minute": "Minute", "minute": "Minute",
@@ -170,13 +175,14 @@
"ms": "ms", "ms": "ms",
"name": "Name", "name": "Name",
"needHomeDir": "If you are a Synology user, [see here](https://kb.synology.com/DSM/tutorial/user_enable_home_service). Users of other systems need to search for how to create a home directory.", "needHomeDir": "If you are a Synology user, [see here](https://kb.synology.com/DSM/tutorial/user_enable_home_service). Users of other systems need to search for how to create a home directory.",
"needRestart": "Need to restart app", "needRestart": "App needs to be restarted",
"net": "Net", "net": "Network",
"netViewType": "Net view type", "netViewType": "Network view type",
"newContainer": "New container", "newContainer": "New container",
"noClient": "No client", "noClient": "No client",
"noInterface": "No interface", "noInterface": "No interface",
"noLineChart": "Do not use line charts", "noLineChart": "Do not use line charts",
"noLineChartForCpu": "Do not use line charts for CPU",
"noNotiPerm": "No notification permissions, possibly no progress indication when downloading app updates.", "noNotiPerm": "No notification permissions, possibly no progress indication when downloading app updates.",
"noOptions": "No options", "noOptions": "No options",
"noPrivateKeyTip": "The private key does not exist, it may have been deleted or there is a configuration error.", "noPrivateKeyTip": "The private key does not exist, it may have been deleted or there is a configuration error.",
@@ -195,22 +201,22 @@
"ok": "OK", "ok": "OK",
"onServerDetailPage": "On server detail page", "onServerDetailPage": "On server detail page",
"onlyOneLine": "Only display as one line (scrollable)", "onlyOneLine": "Only display as one line (scrollable)",
"onlyWhenCoreBiggerThan8": "Works only when the number of cores > 8", "onlyWhenCoreBiggerThan8": "Works only when the number of cores is greater than 8",
"open": "Open", "open": "Open",
"openLastPath": "Open the last path", "openLastPath": "Open the last path",
"openLastPathTip": "Different servers will have different logs, and the log is the path to the exit", "openLastPathTip": "Different servers will have different logs, and the log is the path to the exit",
"parseContainerStats": "Parse the container occupancy status", "parseContainerStatsTip": "Parsing the occupancy status of Docker is relatively slow.",
"parseContainerStatsTip": "Docker parsing the occupancy status is relatively slow.",
"paste": "Paste", "paste": "Paste",
"path": "Path", "path": "Path",
"percentOfSize": "{percent}% of {size}", "percentOfSize": "{percent}% of {size}",
"permission": "Permissions",
"pickFile": "Pick file", "pickFile": "Pick file",
"pingAvg": "Avg:", "pingAvg": "Avg:",
"pingInputIP": "Please input a target IP / domain.", "pingInputIP": "Please input a target IP / domain.",
"pingNoServer": "No server to ping.\nPlease add a server in server tab.", "pingNoServer": "No server to ping.\nPlease add a server in server tab.",
"pkg": "Pkg", "pkg": "Pkg",
"pkgUpgradeTip": "Please backup your system before updating.", "pkgUpgradeTip": "Please backup your system before updating.",
"platformNotSupportUpdate": "Current platform does not support in app update.\nPlease build from source and install it.", "platformNotSupportUpdate": "Current platform does not support in-app update.\nPlease build from source and install it.",
"plugInType": "Insertion Type", "plugInType": "Insertion Type",
"plzEnterHost": "Please enter host.", "plzEnterHost": "Please enter host.",
"plzSelectKey": "Please select a key.", "plzSelectKey": "Please select a key.",
@@ -229,6 +235,7 @@
"rememberChoice": "Remember the selection", "rememberChoice": "Remember the selection",
"rememberPwdInMem": "Remember password in memory", "rememberPwdInMem": "Remember password in memory",
"rememberPwdInMemTip": "Used for containers, suspending, etc.", "rememberPwdInMemTip": "Used for containers, suspending, etc.",
"rememberWindowSize": "Remember window size",
"remotePath": "Remote path", "remotePath": "Remote path",
"rename": "Rename", "rename": "Rename",
"reportBugsOnGithubIssue": "Please report bugs on {url}", "reportBugsOnGithubIssue": "Please report bugs on {url}",
@@ -247,7 +254,7 @@
"sequence": "Sequence", "sequence": "Sequence",
"server": "Server", "server": "Server",
"serverDetailOrder": "Detail page widget order", "serverDetailOrder": "Detail page widget order",
"serverFuncBtns": "Server func buttons", "serverFuncBtns": "Server function buttons",
"serverOrder": "Server order", "serverOrder": "Server order",
"serverTabConnecting": "Connecting...", "serverTabConnecting": "Connecting...",
"serverTabEmpty": "There is no server.\nClick the fab to add one.", "serverTabEmpty": "There is no server.\nClick the fab to add one.",
@@ -257,6 +264,7 @@
"serverTabUnkown": "Unknown state", "serverTabUnkown": "Unknown state",
"setting": "Settings", "setting": "Settings",
"sftpDlPrepare": "Preparing to connect...", "sftpDlPrepare": "Preparing to connect...",
"sftpEditorTip": "If empty, use the built-in file editor of the app. If a value is present, use the remote servers editor, e.g., `vim` (recommended to automatically detect according to `EDITOR`).",
"sftpRmrDirSummary": "Use `rm -r` to delete a folder in SFTP.", "sftpRmrDirSummary": "Use `rm -r` to delete a folder in SFTP.",
"sftpSSHConnected": "SFTP Connected", "sftpSSHConnected": "SFTP Connected",
"sftpShowFoldersFirst": "Display folders first", "sftpShowFoldersFirst": "Display folders first",
@@ -271,14 +279,15 @@
"sshTip": "This function is now in the experimental stage.\n\nPlease report bugs on {url} or join our development.", "sshTip": "This function is now in the experimental stage.\n\nPlease report bugs on {url} or join our development.",
"sshVirtualKeyAutoOff": "Auto switching of virtual keys", "sshVirtualKeyAutoOff": "Auto switching of virtual keys",
"start": "Start", "start": "Start",
"stats": "Stats", "stat": "Statistics",
"stats": "Statistics",
"stop": "Stop", "stop": "Stop",
"stopped": "Stopped", "stopped": "Stopped",
"storage": "Storage", "storage": "Storage",
"success": "Success", "success": "Success",
"supportFmtArgs": "The following formatting parameters are supported:", "supportFmtArgs": "The following formatting parameters are supported:",
"suspend": "Suspend", "suspend": "Suspend",
"suspendTip": "The suspend function requires root privileges and systemd support.", "suspendTip": "The suspend function requires root permission and systemd support.",
"switchTo": "Switch to {val}", "switchTo": "Switch to {val}",
"sync": "Sync", "sync": "Sync",
"syncTip": "A restart may be required for some changes to take effect.", "syncTip": "A restart may be required for some changes to take effect.",
@@ -297,10 +306,10 @@
"total": "Total", "total": "Total",
"traffic": "Traffic", "traffic": "Traffic",
"trySudo": "Try using sudo", "trySudo": "Try using sudo",
"ttl": "ttl", "ttl": "TTL",
"unknown": "Unknown", "unknown": "Unknown",
"unknownError": "Unknown error", "unknownError": "Unknown error",
"unkownConvertMode": "Unknown convert mode", "unkownConvertMode": "Unknown conversion mode",
"update": "Update", "update": "Update",
"updateAll": "Update all", "updateAll": "Update all",
"updateIntervalEqual0": "You set to 0, will not update automatically.\nCan't calculate CPU status.", "updateIntervalEqual0": "You set to 0, will not update automatically.\nCan't calculate CPU status.",
@@ -314,7 +323,7 @@
"useCdn": "Using CDN", "useCdn": "Using CDN",
"useCdnTip": "Non-Chinese users are recommended to use CDN. Would you like to use it?", "useCdnTip": "Non-Chinese users are recommended to use CDN. Would you like to use it?",
"useNoPwd": "No password will be used", "useNoPwd": "No password will be used",
"usePodmanByDefault": "Defaulting to Podman", "usePodmanByDefault": "Use Podman by default",
"used": "Used", "used": "Used",
"user": "User", "user": "User",
"versionHaveUpdate": "Found: v1.0.{build}, click to update", "versionHaveUpdate": "Found: v1.0.{build}, click to update",
@@ -322,16 +331,17 @@
"versionUpdated": "Current: v1.0.{build}, is up to date", "versionUpdated": "Current: v1.0.{build}, is up to date",
"view": "View", "view": "View",
"viewErr": "See error", "viewErr": "See error",
"virtKeyHelpClipboard": "Copy to the clipboard if terminal selected is not empty, otherwise paste the contents of the clipboard to the terminal.", "virtKeyHelpClipboard": "Copy to the clipboard if the selected terminal is not empty, otherwise paste the content of the clipboard to the terminal.",
"virtKeyHelpIME": "Turn on/off the keyboard", "virtKeyHelpIME": "Turn on/off the keyboard",
"virtKeyHelpSFTP": "Open current directory in SFTP.", "virtKeyHelpSFTP": "Open current directory in SFTP.",
"waitConnection": "Please wait for the connection to be established.", "waitConnection": "Please wait for the connection to be established.",
"wakeLock": "Keep awake", "wakeLock": "Keep awake",
"watchNotPaired": "No paired Apple Watch", "watchNotPaired": "No paired Apple Watch",
"webdavSettingEmpty": "Webdav setting is empty", "webdavSettingEmpty": "WebDav setting is empty",
"whenOpenApp": "When opening the app", "whenOpenApp": "When opening the app",
"willTakEeffectImmediately": "Will take effect immediately", "willTakEeffectImmediately": "Will take effect immediately",
"wolTip": "After configuring WOL (Wake-on-LAN), a WOL request is sent each time the server is connected.", "wolTip": "After configuring WOL (Wake-on-LAN), a WOL request is sent each time the server is connected.",
"write": "Write", "write": "Write",
"writeScriptFailTip": "Writing to the script failed, possibly due to lack of permissions or the directory does not exist." "writeScriptFailTip": "Writing to the script failed, possibly due to lack of permissions or the directory does not exist.",
"writeScriptTip": "After connecting to the server, a script will be written to ~/.config/server_box to monitor the system status. You can review the script content."
} }

View File

@@ -2,6 +2,7 @@
"@@locale": "es", "@@locale": "es",
"about": "Acerca de", "about": "Acerca de",
"aboutThanks": "Gracias a los siguientes participantes.", "aboutThanks": "Gracias a los siguientes participantes.",
"acceptBeta": "Aceptar actualizaciones de la versión de prueba",
"add": "Añadir", "add": "Añadir",
"addAServer": "Agregar un servidor", "addAServer": "Agregar un servidor",
"addPrivateKey": "Agregar una llave privada", "addPrivateKey": "Agregar una llave privada",
@@ -10,7 +11,6 @@
"addr": "Dirección", "addr": "Dirección",
"all": "Todos", "all": "Todos",
"alreadyLastDir": "Ya estás en el directorio superior", "alreadyLastDir": "Ya estás en el directorio superior",
"alterUrl": "URL alternativa",
"askContinue": "{msg}, ¿continuar?", "askContinue": "{msg}, ¿continuar?",
"attention": "Atención", "attention": "Atención",
"authFailTip": "La autenticación ha fallado, por favor verifica si la contraseña/llave/host/usuario, etc., son incorrectos.", "authFailTip": "La autenticación ha fallado, por favor verifica si la contraseña/llave/host/usuario, etc., son incorrectos.",
@@ -44,7 +44,6 @@
"cnKeyboardCompTip": "Si el terminal muestra un teclado seguro, puedes activarlo.", "cnKeyboardCompTip": "Si el terminal muestra un teclado seguro, puedes activarlo.",
"collapseUI": "Colapsar", "collapseUI": "Colapsar",
"collapseUITip": "¿Colapsar por defecto las listas largas en la UI?", "collapseUITip": "¿Colapsar por defecto las listas largas en la UI?",
"collectUsage": "Recopilar información de uso (no relacionada con la privacidad).",
"conn": "Conectar", "conn": "Conectar",
"connected": "Conectado", "connected": "Conectado",
"container": "Contenedor", "container": "Contenedor",
@@ -68,7 +67,6 @@
"decode": "Decodificar", "decode": "Decodificar",
"decompress": "Descomprimir", "decompress": "Descomprimir",
"delete": "Eliminar", "delete": "Eliminar",
"deleteScripts": "Eliminar scripts del servidor simultáneamente",
"deleteServers": "Eliminar servidores en lote", "deleteServers": "Eliminar servidores en lote",
"deviceName": "Nombre del dispositivo", "deviceName": "Nombre del dispositivo",
"dirEmpty": "Asegúrate de que el directorio esté vacío", "dirEmpty": "Asegúrate de que el directorio esté vacío",
@@ -94,12 +92,15 @@
"editor": "Editor", "editor": "Editor",
"editorHighlightTip": "El rendimiento del resaltado de código es bastante pobre actualmente, puedes elegir desactivarlo para mejorar.", "editorHighlightTip": "El rendimiento del resaltado de código es bastante pobre actualmente, puedes elegir desactivarlo para mejorar.",
"encode": "Codificar", "encode": "Codificar",
"envVars": "Variable de entorno",
"error": "Error", "error": "Error",
"exampleName": "Ejemplo de nombre", "exampleName": "Ejemplo de nombre",
"experimentalFeature": "Función experimental", "experimentalFeature": "Función experimental",
"export": "Exportar", "export": "Exportar",
"extraArgs": "Argumentos extra", "extraArgs": "Argumentos extra",
"failed": "Fallido", "failed": "Fallido",
"fallbackSshDest": "Destino SSH alternativo",
"fdroidReleaseTip": "Si descargaste esta aplicación desde F-Droid, se recomienda desactivar esta opción.",
"feedback": "Retroalimentación", "feedback": "Retroalimentación",
"feedbackOnGithub": "Si tienes algún problema, por favor informa en GitHub", "feedbackOnGithub": "Si tienes algún problema, por favor informa en GitHub",
"fieldMustNotEmpty": "Estos campos no pueden estar vacíos.", "fieldMustNotEmpty": "Estos campos no pueden estar vacíos.",
@@ -110,6 +111,7 @@
"followSystem": "Seguir al sistema", "followSystem": "Seguir al sistema",
"font": "Fuente", "font": "Fuente",
"fontSize": "Tamaño de fuente", "fontSize": "Tamaño de fuente",
"forExample": "Por ejemplo",
"force": "Forzar", "force": "Forzar",
"foundNUpdate": "Encontradas {count} actualizaciones", "foundNUpdate": "Encontradas {count} actualizaciones",
"fullScreen": "Modo pantalla completa", "fullScreen": "Modo pantalla completa",
@@ -133,6 +135,7 @@
"imagesList": "Lista de imágenes", "imagesList": "Lista de imágenes",
"import": "Importar", "import": "Importar",
"inAppUpdate": "¿Actualizar dentro de la app? De lo contrario, descargar usando un navegador.", "inAppUpdate": "¿Actualizar dentro de la app? De lo contrario, descargar usando un navegador.",
"init": "Inicializar",
"inner": "Interno", "inner": "Interno",
"inputDomainHere": "Introduce el dominio aquí", "inputDomainHere": "Introduce el dominio aquí",
"install": "Instalar", "install": "Instalar",
@@ -151,6 +154,8 @@
"languageName": "Español", "languageName": "Español",
"lastTry": "Último intento", "lastTry": "Último intento",
"launchPage": "Página de lanzamiento", "launchPage": "Página de lanzamiento",
"letterCache": "Caché de letras",
"letterCacheTip": "Recomendado desactivar, pero después de desactivarlo, no se podrán ingresar caracteres CJK.",
"license": "Licencia de código abierto", "license": "Licencia de código abierto",
"light": "Claro", "light": "Claro",
"loadingFiles": "Cargando directorio...", "loadingFiles": "Cargando directorio...",
@@ -177,6 +182,7 @@
"noClient": "No hay conexión SSH", "noClient": "No hay conexión SSH",
"noInterface": "No hay interfaz disponible", "noInterface": "No hay interfaz disponible",
"noLineChart": "No utilice gráficos de líneas", "noLineChart": "No utilice gráficos de líneas",
"noLineChartForCpu": "No utilice gráficos lineales para la CPU",
"noNotiPerm": "Sin permisos de notificación, posiblemente sin indicación de progreso al descargar actualizaciones de la aplicación.", "noNotiPerm": "Sin permisos de notificación, posiblemente sin indicación de progreso al descargar actualizaciones de la aplicación.",
"noOptions": "Sin opciones disponibles", "noOptions": "Sin opciones disponibles",
"noPrivateKeyTip": "La clave privada no existe, puede haber sido eliminada o hay un error de configuración.", "noPrivateKeyTip": "La clave privada no existe, puede haber sido eliminada o hay un error de configuración.",
@@ -199,11 +205,11 @@
"open": "Abrir", "open": "Abrir",
"openLastPath": "Abrir el último camino", "openLastPath": "Abrir el último camino",
"openLastPathTip": "Los diferentes servidores tendrán diferentes registros, y lo que se registra es la ruta de salida", "openLastPathTip": "Los diferentes servidores tendrán diferentes registros, y lo que se registra es la ruta de salida",
"parseContainerStats": "Analizar estado de uso del contenedor",
"parseContainerStatsTip": "El análisis del estado de uso de Docker es bastante lento", "parseContainerStatsTip": "El análisis del estado de uso de Docker es bastante lento",
"paste": "Pegar", "paste": "Pegar",
"path": "Ruta", "path": "Ruta",
"percentOfSize": "El {percent}% de {size}", "percentOfSize": "El {percent}% de {size}",
"permission": "Permisos",
"pickFile": "Seleccionar archivo", "pickFile": "Seleccionar archivo",
"pingAvg": "Promedio:", "pingAvg": "Promedio:",
"pingInputIP": "Por favor, introduce la IP de destino o el dominio", "pingInputIP": "Por favor, introduce la IP de destino o el dominio",
@@ -229,6 +235,7 @@
"rememberChoice": "Recordar la selección", "rememberChoice": "Recordar la selección",
"rememberPwdInMem": "Recordar contraseña en la memoria", "rememberPwdInMem": "Recordar contraseña en la memoria",
"rememberPwdInMemTip": "Utilizado para contenedores, suspensión, etc.", "rememberPwdInMemTip": "Utilizado para contenedores, suspensión, etc.",
"rememberWindowSize": "Recordar el tamaño de la ventana",
"remotePath": "Ruta remota", "remotePath": "Ruta remota",
"rename": "Renombrar", "rename": "Renombrar",
"reportBugsOnGithubIssue": "Por favor, informa los problemas en {url}", "reportBugsOnGithubIssue": "Por favor, informa los problemas en {url}",
@@ -257,6 +264,7 @@
"serverTabUnkown": "Estado desconocido", "serverTabUnkown": "Estado desconocido",
"setting": "Configuración", "setting": "Configuración",
"sftpDlPrepare": "Preparando para conectar al servidor...", "sftpDlPrepare": "Preparando para conectar al servidor...",
"sftpEditorTip": "Si está vacío, use el editor de archivos incorporado de la aplicación. Si hay un valor, use el editor del servidor remoto, por ejemplo, `vim` (se recomienda detectar automáticamente según `EDITOR`).",
"sftpRmrDirSummary": "Usar `rm -r` en SFTP para eliminar directorios", "sftpRmrDirSummary": "Usar `rm -r` en SFTP para eliminar directorios",
"sftpSSHConnected": "SFTP conectado...", "sftpSSHConnected": "SFTP conectado...",
"sftpShowFoldersFirst": "Mostrar carpetas primero", "sftpShowFoldersFirst": "Mostrar carpetas primero",
@@ -271,6 +279,7 @@
"sshTip": "Esta función está en fase de pruebas.\n\nPor favor, informa los problemas en {url}, o únete a nuestro desarrollo.", "sshTip": "Esta función está en fase de pruebas.\n\nPor favor, informa los problemas en {url}, o únete a nuestro desarrollo.",
"sshVirtualKeyAutoOff": "Desactivación automática de teclas virtuales", "sshVirtualKeyAutoOff": "Desactivación automática de teclas virtuales",
"start": "Iniciar", "start": "Iniciar",
"stat": "Estadísticas",
"stats": "Estadísticas", "stats": "Estadísticas",
"stop": "Detener", "stop": "Detener",
"stopped": "Detenido", "stopped": "Detenido",
@@ -297,7 +306,7 @@
"total": "Total", "total": "Total",
"traffic": "Tráfico", "traffic": "Tráfico",
"trySudo": "Intentar con sudo", "trySudo": "Intentar con sudo",
"ttl": "Tiempo de vida (TTL)", "ttl": "TTL",
"unknown": "Desconocido", "unknown": "Desconocido",
"unknownError": "Error desconocido", "unknownError": "Error desconocido",
"unkownConvertMode": "Modo de conversión desconocido", "unkownConvertMode": "Modo de conversión desconocido",
@@ -333,5 +342,6 @@
"willTakEeffectImmediately": "Los cambios tendrán efecto inmediatamente", "willTakEeffectImmediately": "Los cambios tendrán efecto inmediatamente",
"wolTip": "Después de configurar WOL (Wake-on-LAN), se envía una solicitud de WOL cada vez que se conecta el servidor.", "wolTip": "Después de configurar WOL (Wake-on-LAN), se envía una solicitud de WOL cada vez que se conecta el servidor.",
"write": "Escribir", "write": "Escribir",
"writeScriptFailTip": "La escritura en el script falló, posiblemente por falta de permisos o porque el directorio no existe." "writeScriptFailTip": "La escritura en el script falló, posiblemente por falta de permisos o porque el directorio no existe.",
"writeScriptTip": "Después de conectarse al servidor, se escribirá un script en ~/.config/server_box para monitorear el estado del sistema. Puedes revisar el contenido del script."
} }

View File

@@ -2,6 +2,7 @@
"@@locale": "fr", "@@locale": "fr",
"about": "À propos", "about": "À propos",
"aboutThanks": "Merci aux personnes suivantes qui ont participé.", "aboutThanks": "Merci aux personnes suivantes qui ont participé.",
"acceptBeta": "Accepter les mises à jour de la version de test",
"add": "Ajouter", "add": "Ajouter",
"addAServer": "Ajouter un serveur", "addAServer": "Ajouter un serveur",
"addPrivateKey": "Ajouter une clé privée", "addPrivateKey": "Ajouter une clé privée",
@@ -10,7 +11,6 @@
"addr": "Adresse", "addr": "Adresse",
"all": "Tous", "all": "Tous",
"alreadyLastDir": "Déjà dans le dernier répertoire.", "alreadyLastDir": "Déjà dans le dernier répertoire.",
"alterUrl": "Modifier l'URL",
"askContinue": "{msg}. Continuer ?", "askContinue": "{msg}. Continuer ?",
"attention": "Attention", "attention": "Attention",
"authFailTip": "Échec de l'authentification. Veuillez vérifier si le mot de passe/clé/hôte/utilisateur, etc., est incorrect.", "authFailTip": "Échec de l'authentification. Veuillez vérifier si le mot de passe/clé/hôte/utilisateur, etc., est incorrect.",
@@ -44,7 +44,6 @@
"cnKeyboardCompTip": "Si le terminal affiche un clavier sécurisé, vous pouvez l'activer.", "cnKeyboardCompTip": "Si le terminal affiche un clavier sécurisé, vous pouvez l'activer.",
"collapseUI": "Réduire", "collapseUI": "Réduire",
"collapseUITip": "Indique si les longues listes présentées dans l'interface utilisateur doivent être réduites par défaut.", "collapseUITip": "Indique si les longues listes présentées dans l'interface utilisateur doivent être réduites par défaut.",
"collectUsage": "Collecter des informations d'utilisation (sans rapport avec la confidentialité).",
"conn": "Connexion", "conn": "Connexion",
"connected": "Connecté", "connected": "Connecté",
"container": "Conteneur", "container": "Conteneur",
@@ -68,7 +67,6 @@
"decode": "Décoder", "decode": "Décoder",
"decompress": "Décompresser", "decompress": "Décompresser",
"delete": "Supprimer", "delete": "Supprimer",
"deleteScripts": "Supprimer les scripts du serveur en même temps",
"deleteServers": "Supprimer des serveurs en lot", "deleteServers": "Supprimer des serveurs en lot",
"deviceName": "Nom de l'appareil", "deviceName": "Nom de l'appareil",
"dirEmpty": "Assurez-vous que le répertoire est vide.", "dirEmpty": "Assurez-vous que le répertoire est vide.",
@@ -94,12 +92,15 @@
"editor": "Éditeur", "editor": "Éditeur",
"editorHighlightTip": "La performance actuelle de mise en surbrillance du code est pire et peut être désactivée en option pour s'améliorer.", "editorHighlightTip": "La performance actuelle de mise en surbrillance du code est pire et peut être désactivée en option pour s'améliorer.",
"encode": "Encoder", "encode": "Encoder",
"envVars": "Variable denvironnement",
"error": "Erreur", "error": "Erreur",
"exampleName": "Nom de l'exemple", "exampleName": "Nom de l'exemple",
"experimentalFeature": "Fonctionnalité expérimentale", "experimentalFeature": "Fonctionnalité expérimentale",
"export": "Exporter", "export": "Exporter",
"extraArgs": "Arguments supplémentaires", "extraArgs": "Arguments supplémentaires",
"failed": "Échoué", "failed": "Échoué",
"fallbackSshDest": "Destino SSH alternativo",
"fdroidReleaseTip": "Si vous avez téléchargé cette application depuis F-Droid, il est recommandé de désactiver cette option.",
"feedback": "Retour", "feedback": "Retour",
"feedbackOnGithub": "Si vous avez des questions, veuillez donner votre avis sur Github.", "feedbackOnGithub": "Si vous avez des questions, veuillez donner votre avis sur Github.",
"fieldMustNotEmpty": "Ces champs ne doivent pas être vides.", "fieldMustNotEmpty": "Ces champs ne doivent pas être vides.",
@@ -110,6 +111,7 @@
"followSystem": "Suivre le système", "followSystem": "Suivre le système",
"font": "Police", "font": "Police",
"fontSize": "Taille de la police", "fontSize": "Taille de la police",
"forExample": "Par exemple",
"force": "Forcer", "force": "Forcer",
"foundNUpdate": "{count} mise à jour trouvée", "foundNUpdate": "{count} mise à jour trouvée",
"fullScreen": "Mode plein écran", "fullScreen": "Mode plein écran",
@@ -133,6 +135,7 @@
"imagesList": "Liste des images", "imagesList": "Liste des images",
"import": "Importer", "import": "Importer",
"inAppUpdate": "Mettre à jour dans l'application ? Sinon, téléchargez en utilisant un navigateur.", "inAppUpdate": "Mettre à jour dans l'application ? Sinon, téléchargez en utilisant un navigateur.",
"init": "Initialiser",
"inner": "Interne", "inner": "Interne",
"inputDomainHere": "Saisissez le domaine ici", "inputDomainHere": "Saisissez le domaine ici",
"install": "Installer", "install": "Installer",
@@ -151,6 +154,8 @@
"languageName": "Français", "languageName": "Français",
"lastTry": "Dernière tentative", "lastTry": "Dernière tentative",
"launchPage": "Page de lancement", "launchPage": "Page de lancement",
"letterCache": "Mise en cache des lettres",
"letterCacheTip": "Recommandé de désactiver, mais après désactivation, il sera impossible de saisir des caractères CJK.",
"license": "Licence", "license": "Licence",
"light": "Clair", "light": "Clair",
"loadingFiles": "Chargement des fichiers...", "loadingFiles": "Chargement des fichiers...",
@@ -177,6 +182,7 @@
"noClient": "Pas de client", "noClient": "Pas de client",
"noInterface": "Pas d'interface", "noInterface": "Pas d'interface",
"noLineChart": "Ne pas utiliser de graphiques linéaires", "noLineChart": "Ne pas utiliser de graphiques linéaires",
"noLineChartForCpu": "Ne pas utiliser de graphiques linéaires pour l'unité centrale",
"noNotiPerm": "Pas de permissions de notification, peut-être pas d'indication de progression lors de la mise à jour des applications.", "noNotiPerm": "Pas de permissions de notification, peut-être pas d'indication de progression lors de la mise à jour des applications.",
"noOptions": "Pas d'options", "noOptions": "Pas d'options",
"noPrivateKeyTip": "La clé privée n'existe pas, elle a peut-être été supprimée ou il y a une erreur de configuration.", "noPrivateKeyTip": "La clé privée n'existe pas, elle a peut-être été supprimée ou il y a une erreur de configuration.",
@@ -199,11 +205,11 @@
"open": "Ouvrir", "open": "Ouvrir",
"openLastPath": "Ouvrir le dernier chemin", "openLastPath": "Ouvrir le dernier chemin",
"openLastPathTip": "Les différents serveurs auront des journaux différents, et le journal est le chemin vers la sortie", "openLastPathTip": "Les différents serveurs auront des journaux différents, et le journal est le chemin vers la sortie",
"parseContainerStats": "Analyser l'état d'occupation du conteneur",
"parseContainerStatsTip": "L'analyse de l'occupation des conteneurs Docker est relativement lente.", "parseContainerStatsTip": "L'analyse de l'occupation des conteneurs Docker est relativement lente.",
"paste": "Coller", "paste": "Coller",
"path": "Chemin", "path": "Chemin",
"percentOfSize": "{percent}% de {size}", "percentOfSize": "{percent}% de {size}",
"permission": "Permissions",
"pickFile": "Choisir un fichier", "pickFile": "Choisir un fichier",
"pingAvg": "Moy.:", "pingAvg": "Moy.:",
"pingInputIP": "Veuillez saisir une adresse IP / un domaine cible.", "pingInputIP": "Veuillez saisir une adresse IP / un domaine cible.",
@@ -229,6 +235,7 @@
"rememberChoice": "Se souvenir du choix", "rememberChoice": "Se souvenir du choix",
"rememberPwdInMem": "Mémoriser le mot de passe en mémoire", "rememberPwdInMem": "Mémoriser le mot de passe en mémoire",
"rememberPwdInMemTip": "Utilisé pour les conteneurs, la suspension, etc.", "rememberPwdInMemTip": "Utilisé pour les conteneurs, la suspension, etc.",
"rememberWindowSize": "Se souvenir de la taille de la fenêtre",
"remotePath": "Chemin distant", "remotePath": "Chemin distant",
"rename": "Renommer", "rename": "Renommer",
"reportBugsOnGithubIssue": "Veuillez signaler les bugs sur {url}", "reportBugsOnGithubIssue": "Veuillez signaler les bugs sur {url}",
@@ -257,6 +264,7 @@
"serverTabUnkown": "État inconnu", "serverTabUnkown": "État inconnu",
"setting": "Paramètres", "setting": "Paramètres",
"sftpDlPrepare": "Préparation de la connexion...", "sftpDlPrepare": "Préparation de la connexion...",
"sftpEditorTip": "Si vide, utilisez léditeur de fichiers intégré de lapplication. Si une valeur est présente, utilisez léditeur du serveur distant, par exemple `vim` (il est recommandé de détecter automatiquement selon `EDITOR`).",
"sftpRmrDirSummary": "Utilisez `rm -r` pour supprimer un dossier en SFTP.", "sftpRmrDirSummary": "Utilisez `rm -r` pour supprimer un dossier en SFTP.",
"sftpSSHConnected": "SFTP Connecté", "sftpSSHConnected": "SFTP Connecté",
"sftpShowFoldersFirst": "Afficher d'abord les dossiers", "sftpShowFoldersFirst": "Afficher d'abord les dossiers",
@@ -271,6 +279,7 @@
"sshTip": "Cette fonctionnalité est actuellement à l'étape expérimentale.\n\nVeuillez signaler les bugs sur {url} ou rejoindre notre développement.", "sshTip": "Cette fonctionnalité est actuellement à l'étape expérimentale.\n\nVeuillez signaler les bugs sur {url} ou rejoindre notre développement.",
"sshVirtualKeyAutoOff": "Activation automatique des touches virtuelles", "sshVirtualKeyAutoOff": "Activation automatique des touches virtuelles",
"start": "Démarrer", "start": "Démarrer",
"stat": "Statistiques",
"stats": "Statistiques", "stats": "Statistiques",
"stop": "Arrêter", "stop": "Arrêter",
"stopped": "Arrêté", "stopped": "Arrêté",
@@ -297,7 +306,7 @@
"total": "Total", "total": "Total",
"traffic": "Trafic", "traffic": "Trafic",
"trySudo": "Essayer d'utiliser sudo", "trySudo": "Essayer d'utiliser sudo",
"ttl": "ttl", "ttl": "TTL",
"unknown": "Inconnu", "unknown": "Inconnu",
"unknownError": "Erreur inconnue", "unknownError": "Erreur inconnue",
"unkownConvertMode": "Mode de conversion inconnu", "unkownConvertMode": "Mode de conversion inconnu",
@@ -333,5 +342,6 @@
"willTakEeffectImmediately": "Prendra effet immédiatement", "willTakEeffectImmediately": "Prendra effet immédiatement",
"wolTip": "Après avoir configuré le WOL (Wake-on-LAN), une requête WOL est envoyée chaque fois que le serveur est connecté.", "wolTip": "Après avoir configuré le WOL (Wake-on-LAN), une requête WOL est envoyée chaque fois que le serveur est connecté.",
"write": "Écrire", "write": "Écrire",
"writeScriptFailTip": "Échec de l'écriture dans le script, probablement en raison d'un manque de permissions ou que le répertoire n'existe pas." "writeScriptFailTip": "Échec de l'écriture dans le script, probablement en raison d'un manque de permissions ou que le répertoire n'existe pas.",
"writeScriptTip": "Après la connexion au serveur, un script sera écrit dans ~/.config/server_box pour surveiller létat du système. Vous pouvez examiner le contenu du script."
} }

View File

@@ -2,6 +2,7 @@
"@@locale": "id", "@@locale": "id",
"about": "Tentang", "about": "Tentang",
"aboutThanks": "Terima kasih kepada orang -orang berikut yang berpartisipasi.", "aboutThanks": "Terima kasih kepada orang -orang berikut yang berpartisipasi.",
"acceptBeta": "Terima pembaruan versi uji coba",
"add": "Menambahkan", "add": "Menambahkan",
"addAServer": "tambahkan server", "addAServer": "tambahkan server",
"addPrivateKey": "Tambahkan kunci pribadi", "addPrivateKey": "Tambahkan kunci pribadi",
@@ -10,7 +11,6 @@
"addr": "Alamat", "addr": "Alamat",
"all": "Semua", "all": "Semua",
"alreadyLastDir": "Sudah di direktori terakhir.", "alreadyLastDir": "Sudah di direktori terakhir.",
"alterUrl": "Alter url",
"askContinue": "{msg}, lanjutkan?", "askContinue": "{msg}, lanjutkan?",
"attention": "Perhatian", "attention": "Perhatian",
"authFailTip": "Otentikasi gagal, silakan periksa apakah kata sandi/kunci/host/pengguna, dll, salah.", "authFailTip": "Otentikasi gagal, silakan periksa apakah kata sandi/kunci/host/pengguna, dll, salah.",
@@ -44,7 +44,6 @@
"cnKeyboardCompTip": "Jika terminal munculkan keyboard aman, Anda bisa mengaktifkannya.", "cnKeyboardCompTip": "Jika terminal munculkan keyboard aman, Anda bisa mengaktifkannya.",
"collapseUI": "Runtuh", "collapseUI": "Runtuh",
"collapseUITip": "Apakah akan menciutkan daftar panjang yang ada di UI secara default atau tidak", "collapseUITip": "Apakah akan menciutkan daftar panjang yang ada di UI secara default atau tidak",
"collectUsage": "Mengumpulkan informasi penggunaan (tidak terkait dengan privasi).",
"conn": "Koneksi", "conn": "Koneksi",
"connected": "Terhubung", "connected": "Terhubung",
"container": "Wadah", "container": "Wadah",
@@ -68,7 +67,6 @@
"decode": "Membaca sandi", "decode": "Membaca sandi",
"decompress": "Dekompresi", "decompress": "Dekompresi",
"delete": "Menghapus", "delete": "Menghapus",
"deleteScripts": "Menghapus skrip server secara bersamaan",
"deleteServers": "Penghapusan server secara batch", "deleteServers": "Penghapusan server secara batch",
"deviceName": "Nama perangkat", "deviceName": "Nama perangkat",
"dirEmpty": "Pastikan dir kosong.", "dirEmpty": "Pastikan dir kosong.",
@@ -94,12 +92,15 @@
"editor": "Editor", "editor": "Editor",
"editorHighlightTip": "Performa penyorotan kode saat ini lebih buruk, dan dapat dimatikan secara opsional untuk perbaikan.", "editorHighlightTip": "Performa penyorotan kode saat ini lebih buruk, dan dapat dimatikan secara opsional untuk perbaikan.",
"encode": "Menyandi", "encode": "Menyandi",
"envVars": "Variabel lingkungan",
"error": "Kesalahan", "error": "Kesalahan",
"exampleName": "Nama contoh", "exampleName": "Nama contoh",
"experimentalFeature": "Fitur eksperimental", "experimentalFeature": "Fitur eksperimental",
"export": "Ekspor", "export": "Ekspor",
"extraArgs": "Args ekstra", "extraArgs": "Args ekstra",
"failed": "Gagal", "failed": "Gagal",
"fallbackSshDest": "Tujuan SSH mundur",
"fdroidReleaseTip": "Jika Anda mengunduh aplikasi ini dari F-Droid, disarankan untuk mematikan opsi ini.",
"feedback": "Masukan", "feedback": "Masukan",
"feedbackOnGithub": "Jika Anda memiliki pertanyaan, silakan umpan balik tentang GitHub.", "feedbackOnGithub": "Jika Anda memiliki pertanyaan, silakan umpan balik tentang GitHub.",
"fieldMustNotEmpty": "Bidang -bidang ini tidak boleh kosong.", "fieldMustNotEmpty": "Bidang -bidang ini tidak boleh kosong.",
@@ -110,6 +111,7 @@
"followSystem": "Ikuti sistem", "followSystem": "Ikuti sistem",
"font": "Font", "font": "Font",
"fontSize": "Ukuran huruf", "fontSize": "Ukuran huruf",
"forExample": "Sebagai contoh",
"force": "sukarela", "force": "sukarela",
"foundNUpdate": "Menemukan {count} pembaruan", "foundNUpdate": "Menemukan {count} pembaruan",
"fullScreen": "Mode Layar Penuh", "fullScreen": "Mode Layar Penuh",
@@ -133,6 +135,7 @@
"imagesList": "Daftar gambar", "imagesList": "Daftar gambar",
"import": "Impor", "import": "Impor",
"inAppUpdate": "Perbarui di dalam aplikasi? Jika tidak, unduh menggunakan browser.", "inAppUpdate": "Perbarui di dalam aplikasi? Jika tidak, unduh menggunakan browser.",
"init": "Menginisialisasi",
"inner": "Batin", "inner": "Batin",
"inputDomainHere": "Input domain di sini", "inputDomainHere": "Input domain di sini",
"install": "Install", "install": "Install",
@@ -151,6 +154,8 @@
"languageName": "Indonesia", "languageName": "Indonesia",
"lastTry": "Percobaan terakhir", "lastTry": "Percobaan terakhir",
"launchPage": "Halaman peluncuran", "launchPage": "Halaman peluncuran",
"letterCache": "Caching huruf",
"letterCacheTip": "Direkomendasikan untuk menonaktifkan, tetapi setelah dinonaktifkan, tidak mungkin untuk memasukkan karakter CJK.",
"license": "Lisensi", "license": "Lisensi",
"light": "Terang", "light": "Terang",
"loadingFiles": "Memuat file ...", "loadingFiles": "Memuat file ...",
@@ -171,12 +176,13 @@
"name": "Nama", "name": "Nama",
"needHomeDir": "Jika Anda pengguna Synology, [lihat di sini](https://kb.synology.com/DSM/tutorial/user_enable_home_service). Pengguna sistem lain perlu mencari cara membuat direktori home.", "needHomeDir": "Jika Anda pengguna Synology, [lihat di sini](https://kb.synology.com/DSM/tutorial/user_enable_home_service). Pengguna sistem lain perlu mencari cara membuat direktori home.",
"needRestart": "Perlu memulai ulang aplikasi", "needRestart": "Perlu memulai ulang aplikasi",
"net": "Net", "net": "Jaringan",
"netViewType": "Jenis tampilan bersih", "netViewType": "Jenis tampilan bersih",
"newContainer": "Wadah baru", "newContainer": "Wadah baru",
"noClient": "Tidak ada klien", "noClient": "Tidak ada klien",
"noInterface": "Tidak ada antarmuka", "noInterface": "Tidak ada antarmuka",
"noLineChart": "Jangan gunakan grafik garis", "noLineChart": "Jangan gunakan grafik garis",
"noLineChartForCpu": "Jangan gunakan diagram garis untuk CPU",
"noNotiPerm": "Tidak ada izin notifikasi, mungkin tidak ada indikasi kemajuan saat mengunduh pembaruan aplikasi.", "noNotiPerm": "Tidak ada izin notifikasi, mungkin tidak ada indikasi kemajuan saat mengunduh pembaruan aplikasi.",
"noOptions": "Tidak ada opsi", "noOptions": "Tidak ada opsi",
"noPrivateKeyTip": "Kunci privat tidak ada, mungkin telah dihapus atau ada kesalahan konfigurasi.", "noPrivateKeyTip": "Kunci privat tidak ada, mungkin telah dihapus atau ada kesalahan konfigurasi.",
@@ -199,11 +205,11 @@
"open": "Membuka", "open": "Membuka",
"openLastPath": "Buka jalur terakhir", "openLastPath": "Buka jalur terakhir",
"openLastPathTip": "Server yang berbeda akan memiliki catatan yang berbeda, dan catatan tersebut adalah jalur menuju pintu keluar", "openLastPathTip": "Server yang berbeda akan memiliki catatan yang berbeda, dan catatan tersebut adalah jalur menuju pintu keluar",
"parseContainerStats": "Memecahkan status okupansi kontainer",
"parseContainerStatsTip": "Parsing status okupansi oleh Docker agak lambat", "parseContainerStatsTip": "Parsing status okupansi oleh Docker agak lambat",
"paste": "Tempel", "paste": "Tempel",
"path": "Jalur", "path": "Jalur",
"percentOfSize": "{percent}% dari {size}", "percentOfSize": "{percent}% dari {size}",
"permission": "Izin",
"pickFile": "Pilih file", "pickFile": "Pilih file",
"pingAvg": "Rata -rata:", "pingAvg": "Rata -rata:",
"pingInputIP": "Harap masukkan IP / domain target.", "pingInputIP": "Harap masukkan IP / domain target.",
@@ -229,6 +235,7 @@
"rememberChoice": "Ingat pilihan", "rememberChoice": "Ingat pilihan",
"rememberPwdInMem": "Ingat kata sandi di dalam memori", "rememberPwdInMem": "Ingat kata sandi di dalam memori",
"rememberPwdInMemTip": "Digunakan untuk kontainer, menangguhkan, dll.", "rememberPwdInMemTip": "Digunakan untuk kontainer, menangguhkan, dll.",
"rememberWindowSize": "Ingat ukuran jendela",
"remotePath": "Jalur jarak jauh", "remotePath": "Jalur jarak jauh",
"rename": "Ganti nama", "rename": "Ganti nama",
"reportBugsOnGithubIssue": "Harap laporkan bug di {url}", "reportBugsOnGithubIssue": "Harap laporkan bug di {url}",
@@ -257,6 +264,7 @@
"serverTabUnkown": "Negara yang tidak diketahui", "serverTabUnkown": "Negara yang tidak diketahui",
"setting": "Pengaturan", "setting": "Pengaturan",
"sftpDlPrepare": "Bersiap untuk terhubung ...", "sftpDlPrepare": "Bersiap untuk terhubung ...",
"sftpEditorTip": "Jika kosong, gunakan editor file bawaan aplikasi. Jika ada nilai, gunakan editor server jarak jauh, misalnya `vim` (disarankan untuk mendeteksi secara otomatis sesuai `EDITOR`).",
"sftpRmrDirSummary": "Gunakan `rm -r` untuk menghapus dir di SFTP", "sftpRmrDirSummary": "Gunakan `rm -r` untuk menghapus dir di SFTP",
"sftpSSHConnected": "Sftp terhubung", "sftpSSHConnected": "Sftp terhubung",
"sftpShowFoldersFirst": "Folder ditampilkan lebih dulu", "sftpShowFoldersFirst": "Folder ditampilkan lebih dulu",
@@ -271,6 +279,7 @@
"sshTip": "Fungsi ini sekarang dalam tahap eksperimen.\n\nHarap laporkan bug di {url} atau bergabunglah dengan pengembangan kami.", "sshTip": "Fungsi ini sekarang dalam tahap eksperimen.\n\nHarap laporkan bug di {url} atau bergabunglah dengan pengembangan kami.",
"sshVirtualKeyAutoOff": "Switching Otomatis Kunci Virtual", "sshVirtualKeyAutoOff": "Switching Otomatis Kunci Virtual",
"start": "Awal", "start": "Awal",
"stat": "Statistik",
"stats": "Statistik", "stats": "Statistik",
"stop": "Berhenti", "stop": "Berhenti",
"stopped": "dihentikan", "stopped": "dihentikan",
@@ -297,7 +306,7 @@
"total": "Total", "total": "Total",
"traffic": "Lalu lintas", "traffic": "Lalu lintas",
"trySudo": "Cobalah menggunakan sudo", "trySudo": "Cobalah menggunakan sudo",
"ttl": "ttl", "ttl": "TTL",
"unknown": "Tidak dikenal", "unknown": "Tidak dikenal",
"unknownError": "Kesalahan yang tidak diketahui", "unknownError": "Kesalahan yang tidak diketahui",
"unkownConvertMode": "Mode Konversi Tidak Diketahui", "unkownConvertMode": "Mode Konversi Tidak Diketahui",
@@ -333,5 +342,6 @@
"willTakEeffectImmediately": "Akan segera berlaku", "willTakEeffectImmediately": "Akan segera berlaku",
"wolTip": "Setelah mengonfigurasi WOL (Wake-on-LAN), permintaan WOL dikirim setiap kali server terhubung.", "wolTip": "Setelah mengonfigurasi WOL (Wake-on-LAN), permintaan WOL dikirim setiap kali server terhubung.",
"write": "Tulis", "write": "Tulis",
"writeScriptFailTip": "Penulisan ke skrip gagal, mungkin karena tidak ada izin atau direktori tidak ada." "writeScriptFailTip": "Penulisan ke skrip gagal, mungkin karena tidak ada izin atau direktori tidak ada.",
"writeScriptTip": "Setelah terhubung ke server, sebuah skrip akan ditulis ke ~/.config/server_box untuk memantau status sistem. Anda dapat meninjau konten skrip tersebut."
} }

View File

@@ -2,15 +2,15 @@
"@@locale": "ja", "@@locale": "ja",
"about": "約", "about": "約",
"aboutThanks": "以下の参加者に感謝します。", "aboutThanks": "以下の参加者に感謝します。",
"acceptBeta": "テストバージョンの更新を受け入れる",
"add": "追加", "add": "追加",
"addAServer": "サーバーを追加する", "addAServer": "サーバーを追加する",
"addPrivateKey": "プライベートキーを追加", "addPrivateKey": "秘密鍵を追加",
"addSystemPrivateKeyTip": "現在プライベートキーがありません。システムのデフォルト(~/.ssh/id_rsa)を追加しますか?", "addSystemPrivateKeyTip": "現在秘密鍵がありません。システムのデフォルト(~/.ssh/id_rsa)を追加しますか?",
"added2List": "タスクリストに追加されました", "added2List": "タスクリストに追加されました",
"addr": "住所", "addr": "アドレス",
"all": "すべて", "all": "すべて",
"alreadyLastDir": "すでに最上位のディレクトリです", "alreadyLastDir": "すでに最上位のディレクトリです",
"alterUrl": "代替リンク",
"askContinue": "{msg}、続行しますか?", "askContinue": "{msg}、続行しますか?",
"attention": "注意", "attention": "注意",
"authFailTip": "認証に失敗しました。パスワード/鍵/ホスト/ユーザーなどが間違っていないか確認してください。", "authFailTip": "認証に失敗しました。パスワード/鍵/ホスト/ユーザーなどが間違っていないか確認してください。",
@@ -26,7 +26,7 @@
"backupVersionNotMatch": "バックアップバージョンが一致しないため、復元できません", "backupVersionNotMatch": "バックアップバージョンが一致しないため、復元できません",
"battery": "バッテリー", "battery": "バッテリー",
"bgRun": "バックグラウンド実行", "bgRun": "バックグラウンド実行",
"bgRunTip": "このスイッチはプログラムがバックグラウンドで実行を試みることを意味しますが、実際にバックグラウンドで実行できるかどうかは、権限が有効になっているかに依存します。ネイティブAndroidでは、このアプリの「バッテリー最適化」をオフにしてください。MIUIでは、省エネモードを「無制限」に変更してください。", "bgRunTip": "このスイッチはプログラムがバックグラウンドで実行を試みることを意味しますが、実際にバックグラウンドで実行できるかどうかは、権限が有効になっているかに依存します。AOSPベースのAndroid ROMでは、このアプリの「バッテリー最適化」をオフにしてください。MIUIでは、省エネモードを「無制限」に変更してください。",
"bioAuth": "生体認証", "bioAuth": "生体認証",
"browser": "ブラウザ", "browser": "ブラウザ",
"bulkImportServers": "サーバーを一括インポートする", "bulkImportServers": "サーバーを一括インポートする",
@@ -35,7 +35,7 @@
"cancel": "キャンセル", "cancel": "キャンセル",
"choose": "選択", "choose": "選択",
"chooseFontFile": "フォントファイルを選択", "chooseFontFile": "フォントファイルを選択",
"choosePrivateKey": "プライベートキーを選択", "choosePrivateKey": "秘密鍵を選択",
"clear": "クリア", "clear": "クリア",
"clipboard": "クリップボード", "clipboard": "クリップボード",
"close": "閉じる", "close": "閉じる",
@@ -44,7 +44,6 @@
"cnKeyboardCompTip": "ターミナルがセキュアキーボードを表示した場合、それを有効にできます。", "cnKeyboardCompTip": "ターミナルがセキュアキーボードを表示した場合、それを有効にできます。",
"collapseUI": "UIを折りたたむ", "collapseUI": "UIを折りたたむ",
"collapseUITip": "UIの長いリストをデフォルトで折りたたむかどうか", "collapseUITip": "UIの長いリストをデフォルトで折りたたむかどうか",
"collectUsage": "使用情報を収集する(プライバシーとは関係ない)。",
"conn": "接続", "conn": "接続",
"connected": "接続済み", "connected": "接続済み",
"container": "コンテナ", "container": "コンテナ",
@@ -68,7 +67,6 @@
"decode": "デコード", "decode": "デコード",
"decompress": "解凍", "decompress": "解凍",
"delete": "削除", "delete": "削除",
"deleteScripts": "サーバースクリプトも削除",
"deleteServers": "サーバーを一括削除", "deleteServers": "サーバーを一括削除",
"deviceName": "デバイス名", "deviceName": "デバイス名",
"dirEmpty": "フォルダーが空であることを確認してください", "dirEmpty": "フォルダーが空であることを確認してください",
@@ -94,12 +92,15 @@
"editor": "エディター", "editor": "エディター",
"editorHighlightTip": "現在のコードハイライトのパフォーマンスはかなり悪いため、改善するために無効にすることを選択できます。", "editorHighlightTip": "現在のコードハイライトのパフォーマンスはかなり悪いため、改善するために無効にすることを選択できます。",
"encode": "エンコード", "encode": "エンコード",
"envVars": "環境変数",
"error": "エラー", "error": "エラー",
"exampleName": "名前例", "exampleName": "名前例",
"experimentalFeature": "実験的な機能", "experimentalFeature": "実験的な機能",
"export": "エクスポート", "export": "エクスポート",
"extraArgs": "追加引数", "extraArgs": "追加引数",
"failed": "失敗しました", "failed": "失敗しました",
"fallbackSshDest": "フォールバックSSH宛先",
"fdroidReleaseTip": "このアプリをF-Droidからダウンロードした場合、このオプションをオフにすることをお勧めします。",
"feedback": "フィードバック", "feedback": "フィードバック",
"feedbackOnGithub": "問題がある場合は、GitHubでフィードバックしてください", "feedbackOnGithub": "問題がある場合は、GitHubでフィードバックしてください",
"fieldMustNotEmpty": "これらの入力フィールドは空にできません。", "fieldMustNotEmpty": "これらの入力フィールドは空にできません。",
@@ -110,6 +111,7 @@
"followSystem": "システムに従う", "followSystem": "システムに従う",
"font": "フォント", "font": "フォント",
"fontSize": "フォントサイズ", "fontSize": "フォントサイズ",
"forExample": "例えば",
"force": "強制", "force": "強制",
"foundNUpdate": "{count}個の更新が見つかりました", "foundNUpdate": "{count}個の更新が見つかりました",
"fullScreen": "フルスクリーンモード", "fullScreen": "フルスクリーンモード",
@@ -133,6 +135,7 @@
"imagesList": "イメージリスト", "imagesList": "イメージリスト",
"import": "インポート", "import": "インポート",
"inAppUpdate": "アプリ内で更新しますか?それ以外の場合は、ブラウザを使用してダウンロードしてください。", "inAppUpdate": "アプリ内で更新しますか?それ以外の場合は、ブラウザを使用してダウンロードしてください。",
"init": "初期化する",
"inner": "内蔵", "inner": "内蔵",
"inputDomainHere": "ここにドメインを入力", "inputDomainHere": "ここにドメインを入力",
"install": "インストール", "install": "インストール",
@@ -151,6 +154,8 @@
"languageName": "日本語", "languageName": "日本語",
"lastTry": "最後の試み", "lastTry": "最後の試み",
"launchPage": "起動ページ", "launchPage": "起動ページ",
"letterCache": "文字キャッシング",
"letterCacheTip": "無効にすることを推奨しますが、無効にした後はCJK文字を入力することができなくなります。",
"license": "オープンソースライセンス", "license": "オープンソースライセンス",
"light": "ライト", "light": "ライト",
"loadingFiles": "ディレクトリを読み込んでいます...", "loadingFiles": "ディレクトリを読み込んでいます...",
@@ -177,12 +182,13 @@
"noClient": "SSH接続がありません", "noClient": "SSH接続がありません",
"noInterface": "使用可能なインターフェースがありません", "noInterface": "使用可能なインターフェースがありません",
"noLineChart": "折れ線グラフを使用しない", "noLineChart": "折れ線グラフを使用しない",
"noLineChartForCpu": "CPUに折れ線グラフを使わない",
"noNotiPerm": "通知の権限がないため、アプリの更新のダウンロード中に進行状況が表示されない場合があります。", "noNotiPerm": "通知の権限がないため、アプリの更新のダウンロード中に進行状況が表示されない場合があります。",
"noOptions": "選択肢がありません", "noOptions": "選択肢がありません",
"noPrivateKeyTip": "私有鍵が存在しません。削除されたか、設定ミスがある可能性があります。", "noPrivateKeyTip": "秘密鍵が存在しません。削除されたか、設定ミスがある可能性があります。",
"noPromptAgain": "再度確認しない", "noPromptAgain": "再度確認しない",
"noResult": "結果なし", "noResult": "結果なし",
"noSavedPrivateKey": "保存されたプライベートキーがありません。", "noSavedPrivateKey": "保存された秘密鍵がありません。",
"noSavedSnippet": "保存されたスニペットがありません。", "noSavedSnippet": "保存されたスニペットがありません。",
"noServerAvailable": "使用可能なサーバーがありません。", "noServerAvailable": "使用可能なサーバーがありません。",
"noTask": "タスクがありません", "noTask": "タスクがありません",
@@ -199,11 +205,11 @@
"open": "開く", "open": "開く",
"openLastPath": "最後のパスを開く", "openLastPath": "最後のパスを開く",
"openLastPathTip": "異なるサーバーには異なる記録があり、記録されているのは退出時のパスです", "openLastPathTip": "異なるサーバーには異なる記録があり、記録されているのは退出時のパスです",
"parseContainerStats": "コンテナ使用状況を解析",
"parseContainerStatsTip": "Dockerの使用状況の解析は比較的遅いです", "parseContainerStatsTip": "Dockerの使用状況の解析は比較的遅いです",
"paste": "貼り付け", "paste": "貼り付け",
"path": "パス", "path": "パス",
"percentOfSize": "{size} の {percent}%", "percentOfSize": "{size} の {percent}%",
"permission": "権限",
"pickFile": "ファイルを選択", "pickFile": "ファイルを選択",
"pingAvg": "平均:", "pingAvg": "平均:",
"pingInputIP": "対象のIPまたはドメインを入力してください", "pingInputIP": "対象のIPまたはドメインを入力してください",
@@ -213,11 +219,11 @@
"platformNotSupportUpdate": "現在のプラットフォームは更新をサポートしていません。最新のソースコードをコンパイルして手動でインストールしてください", "platformNotSupportUpdate": "現在のプラットフォームは更新をサポートしていません。最新のソースコードをコンパイルして手動でインストールしてください",
"plugInType": "挿入タイプ", "plugInType": "挿入タイプ",
"plzEnterHost": "ホストを入力してください", "plzEnterHost": "ホストを入力してください",
"plzSelectKey": "プライベートキーを選択してください", "plzSelectKey": "秘密鍵を選択してください",
"port": "ポート", "port": "ポート",
"preview": "プレビュー", "preview": "プレビュー",
"primaryColorSeed": "プライマリーカラーシード", "primaryColorSeed": "プライマリーカラーシード",
"privateKey": "プライベートキー", "privateKey": "秘密鍵",
"process": "プロセス", "process": "プロセス",
"pushToken": "プッシュトークン", "pushToken": "プッシュトークン",
"pveIgnoreCertTip": "オプションを有効にすることは推奨されません、セキュリティリスクに注意してくださいPVEのデフォルト証明書を使用している場合は、このオプションを有効にする必要があります。", "pveIgnoreCertTip": "オプションを有効にすることは推奨されません、セキュリティリスクに注意してくださいPVEのデフォルト証明書を使用している場合は、このオプションを有効にする必要があります。",
@@ -229,6 +235,7 @@
"rememberChoice": "選択を記憶する", "rememberChoice": "選択を記憶する",
"rememberPwdInMem": "メモリにパスワードを記憶する", "rememberPwdInMem": "メモリにパスワードを記憶する",
"rememberPwdInMemTip": "コンテナ、一時停止などに使用されます。", "rememberPwdInMemTip": "コンテナ、一時停止などに使用されます。",
"rememberWindowSize": "ウィンドウサイズを記憶する",
"remotePath": "リモートパス", "remotePath": "リモートパス",
"rename": "名前を変更", "rename": "名前を変更",
"reportBugsOnGithubIssue": "{url}で問題を報告してください", "reportBugsOnGithubIssue": "{url}で問題を報告してください",
@@ -253,10 +260,11 @@
"serverTabEmpty": "現在サーバーはありません。\n右下のボタンをクリックして追加してください。", "serverTabEmpty": "現在サーバーはありません。\n右下のボタンをクリックして追加してください。",
"serverTabFailed": "失敗", "serverTabFailed": "失敗",
"serverTabLoading": "読み込み中...", "serverTabLoading": "読み込み中...",
"serverTabPlzSave": "このプライベートキーを再保存してください", "serverTabPlzSave": "この秘密鍵を再保存してください",
"serverTabUnkown": "不明な状態", "serverTabUnkown": "不明な状態",
"setting": "設定", "setting": "設定",
"sftpDlPrepare": "サーバーへの接続を準備中...", "sftpDlPrepare": "サーバーへの接続を準備中...",
"sftpEditorTip": "空の場合は、アプリ内蔵のファイルエディタを使用します。値がある場合は、リモートサーバーのエディタ(例:`vim`)を使用します(`EDITOR` に従って自動検出することをお勧めします)。",
"sftpRmrDirSummary": "SFTPで`rm -r`を使用してフォルダーを削除", "sftpRmrDirSummary": "SFTPで`rm -r`を使用してフォルダーを削除",
"sftpSSHConnected": "SFTPに接続されました...", "sftpSSHConnected": "SFTPに接続されました...",
"sftpShowFoldersFirst": "フォルダーを先に表示", "sftpShowFoldersFirst": "フォルダーを先に表示",
@@ -271,6 +279,7 @@
"sshTip": "この機能は現在テスト段階にあります。\n\n問題がある場合は、{url}でフィードバックしてください。", "sshTip": "この機能は現在テスト段階にあります。\n\n問題がある場合は、{url}でフィードバックしてください。",
"sshVirtualKeyAutoOff": "仮想キーの自動オフ", "sshVirtualKeyAutoOff": "仮想キーの自動オフ",
"start": "開始", "start": "開始",
"stat": "統計",
"stats": "統計", "stats": "統計",
"stop": "停止", "stop": "停止",
"stopped": "停止しました", "stopped": "停止しました",
@@ -333,5 +342,6 @@
"willTakEeffectImmediately": "変更は即座に有効になります", "willTakEeffectImmediately": "変更は即座に有効になります",
"wolTip": "WOLWake-on-LANを設定した後、サーバーに接続するたびにWOLリクエストが送信されます。", "wolTip": "WOLWake-on-LANを設定した後、サーバーに接続するたびにWOLリクエストが送信されます。",
"write": "書き込み", "write": "書き込み",
"writeScriptFailTip": "スクリプトの書き込みに失敗しました。権限がないかディレクトリが存在しない可能性があります。" "writeScriptFailTip": "スクリプトの書き込みに失敗しました。権限がないかディレクトリが存在しない可能性があります。",
"writeScriptTip": "サーバーに接続すると、システムの状態を監視するためのスクリプトが ~/.config/server_box に書き込まれます。スクリプトの内容を確認できます。"
} }

View File

@@ -2,6 +2,7 @@
"@@locale": "nl", "@@locale": "nl",
"about": "Over", "about": "Over",
"aboutThanks": "Met dank aan de volgende mensen die hebben deelgenomen aan.", "aboutThanks": "Met dank aan de volgende mensen die hebben deelgenomen aan.",
"acceptBeta": "Accepteer testversie-updates",
"add": "Toevoegen", "add": "Toevoegen",
"addAServer": "een server toevoegen", "addAServer": "een server toevoegen",
"addPrivateKey": "Privésleutel toevoegen", "addPrivateKey": "Privésleutel toevoegen",
@@ -10,7 +11,6 @@
"addr": "Adres", "addr": "Adres",
"all": "Alle", "all": "Alle",
"alreadyLastDir": "Al in de laatst gebruikte map.", "alreadyLastDir": "Al in de laatst gebruikte map.",
"alterUrl": "Url wijzigen",
"askContinue": "{msg}. Doorgaan?", "askContinue": "{msg}. Doorgaan?",
"attention": "Let op", "attention": "Let op",
"authFailTip": "Authenticatie mislukt, controleer of het wachtwoord/sleutel/host/gebruiker, enz., incorrect zijn.", "authFailTip": "Authenticatie mislukt, controleer of het wachtwoord/sleutel/host/gebruiker, enz., incorrect zijn.",
@@ -44,7 +44,6 @@
"cnKeyboardCompTip": "Als de terminal een beveiligd toetsenbord weergeeft, kunt u dit inschakelen.", "cnKeyboardCompTip": "Als de terminal een beveiligd toetsenbord weergeeft, kunt u dit inschakelen.",
"collapseUI": "Inklappen", "collapseUI": "Inklappen",
"collapseUITip": "Of lange lijsten in de UI standaard moeten worden ingeklapt", "collapseUITip": "Of lange lijsten in de UI standaard moeten worden ingeklapt",
"collectUsage": "Gebruiksinformatie verzamelen (niet gerelateerd aan privacy).",
"conn": "Verbinding", "conn": "Verbinding",
"connected": "Verbonden", "connected": "Verbonden",
"container": "Container", "container": "Container",
@@ -68,7 +67,6 @@
"decode": "Decoderen", "decode": "Decoderen",
"decompress": "Decomprimeren", "decompress": "Decomprimeren",
"delete": "Verwijderen", "delete": "Verwijderen",
"deleteScripts": "Verwijder tegelijkertijd serverscripts",
"deleteServers": "Servers batchgewijs verwijderen", "deleteServers": "Servers batchgewijs verwijderen",
"deviceName": "Apparaatnaam", "deviceName": "Apparaatnaam",
"dirEmpty": "Zorg ervoor dat de map leeg is.", "dirEmpty": "Zorg ervoor dat de map leeg is.",
@@ -94,12 +92,15 @@
"editor": "Editor", "editor": "Editor",
"editorHighlightTip": "De huidige codehighlighting-prestaties zijn slechter en kunnen optioneel worden uitgeschakeld om te verbeteren.", "editorHighlightTip": "De huidige codehighlighting-prestaties zijn slechter en kunnen optioneel worden uitgeschakeld om te verbeteren.",
"encode": "Coderen", "encode": "Coderen",
"envVars": "Omgevingsvariabele",
"error": "Fout", "error": "Fout",
"exampleName": "Voorbeeldnaam", "exampleName": "Voorbeeldnaam",
"experimentalFeature": "Experimentele functie", "experimentalFeature": "Experimentele functie",
"export": "Exporteren", "export": "Exporteren",
"extraArgs": "Extra argumenten", "extraArgs": "Extra argumenten",
"failed": "Mislukt", "failed": "Mislukt",
"fallbackSshDest": "Fallback SSH-bestemming",
"fdroidReleaseTip": "Als u deze app van F-Droid heeft gedownload, wordt aanbevolen deze optie uit te schakelen.",
"feedback": "Feedback", "feedback": "Feedback",
"feedbackOnGithub": "Als je vragen hebt, geef dan feedback op Github.", "feedbackOnGithub": "Als je vragen hebt, geef dan feedback op Github.",
"fieldMustNotEmpty": "Deze velden mogen niet leeg zijn.", "fieldMustNotEmpty": "Deze velden mogen niet leeg zijn.",
@@ -110,6 +111,7 @@
"followSystem": "Volg systeem", "followSystem": "Volg systeem",
"font": "Lettertype", "font": "Lettertype",
"fontSize": "Lettergrootte", "fontSize": "Lettergrootte",
"forExample": "Bijvoorbeeld",
"force": "Forceer", "force": "Forceer",
"foundNUpdate": "{count} update gevonden", "foundNUpdate": "{count} update gevonden",
"fullScreen": "Volledig schermmodus", "fullScreen": "Volledig schermmodus",
@@ -133,6 +135,7 @@
"imagesList": "Lijst met afbeeldingen", "imagesList": "Lijst met afbeeldingen",
"import": "Importeren", "import": "Importeren",
"inAppUpdate": "Bijwerken binnen de app? Anders downloaden via een browser.", "inAppUpdate": "Bijwerken binnen de app? Anders downloaden via een browser.",
"init": "Initialiseren",
"inner": "Intern", "inner": "Intern",
"inputDomainHere": "Voer hier domein in", "inputDomainHere": "Voer hier domein in",
"install": "Installeren", "install": "Installeren",
@@ -151,6 +154,8 @@
"languageName": "Nederlands", "languageName": "Nederlands",
"lastTry": "Laatste poging", "lastTry": "Laatste poging",
"launchPage": "Startpagina", "launchPage": "Startpagina",
"letterCache": "Lettercaching",
"letterCacheTip": "Aanbevolen om uit te schakelen, maar na het uitschakelen is het niet mogelijk om CJK-tekens in te voeren.",
"license": "Licentie", "license": "Licentie",
"light": "Licht", "light": "Licht",
"loadingFiles": "Bestanden laden...", "loadingFiles": "Bestanden laden...",
@@ -176,6 +181,8 @@
"newContainer": "Nieuwe container", "newContainer": "Nieuwe container",
"noClient": "Geen client", "noClient": "Geen client",
"noInterface": "Geen interface", "noInterface": "Geen interface",
"noLineChart": "lijndiagrammen gebruiken",
"noLineChartForCpu": "Gebruik geen lijndiagrammen voor CPU",
"noNotiPerm": "Geen meldingsmachtigingen, mogelijk geen voortgangsindicatie bij het downloaden van app-updates.", "noNotiPerm": "Geen meldingsmachtigingen, mogelijk geen voortgangsindicatie bij het downloaden van app-updates.",
"noOptions": "Geen opties", "noOptions": "Geen opties",
"noPrivateKeyTip": "De privésleutel bestaat niet, deze is mogelijk verwijderd of er is een configuratiefout.", "noPrivateKeyTip": "De privésleutel bestaat niet, deze is mogelijk verwijderd of er is een configuratiefout.",
@@ -198,11 +205,11 @@
"open": "Openen", "open": "Openen",
"openLastPath": "Open het laatste pad", "openLastPath": "Open het laatste pad",
"openLastPathTip": "Verschillende servers hebben verschillende logs, en de log is het pad naar de uitgang", "openLastPathTip": "Verschillende servers hebben verschillende logs, en de log is het pad naar de uitgang",
"parseContainerStats": "Parseer de containerbezettingstatus",
"parseContainerStatsTip": "Het parsen van de bezettingsstatus van Docker is relatief langzaam.", "parseContainerStatsTip": "Het parsen van de bezettingsstatus van Docker is relatief langzaam.",
"paste": "Plakken", "paste": "Plakken",
"path": "Pad", "path": "Pad",
"percentOfSize": "{percent}% van {size}", "percentOfSize": "{percent}% van {size}",
"permission": "Machtigingen",
"pickFile": "Bestand kiezen", "pickFile": "Bestand kiezen",
"pingAvg": "Gem:", "pingAvg": "Gem:",
"pingInputIP": "Voer een doel-IP / domein in.", "pingInputIP": "Voer een doel-IP / domein in.",
@@ -228,6 +235,7 @@
"rememberChoice": "Selectie onthouden", "rememberChoice": "Selectie onthouden",
"rememberPwdInMem": "Wachtwoord onthouden in geheugen", "rememberPwdInMem": "Wachtwoord onthouden in geheugen",
"rememberPwdInMemTip": "Gebruikt voor containers, opschorting, enz.", "rememberPwdInMemTip": "Gebruikt voor containers, opschorting, enz.",
"rememberWindowSize": "Venstergrootte onthouden",
"remotePath": "Extern pad", "remotePath": "Extern pad",
"rename": "Hernoemen", "rename": "Hernoemen",
"reportBugsOnGithubIssue": "Meld alstublieft bugs op {url}", "reportBugsOnGithubIssue": "Meld alstublieft bugs op {url}",
@@ -256,6 +264,7 @@
"serverTabUnkown": "Onbekende status", "serverTabUnkown": "Onbekende status",
"setting": "Instellingen", "setting": "Instellingen",
"sftpDlPrepare": "Voorbereiden om verbinding te maken...", "sftpDlPrepare": "Voorbereiden om verbinding te maken...",
"sftpEditorTip": "Indien leeg, gebruik de ingebouwde bestandseditor van de app. Indien een waarde aanwezig is, gebruik de editor van de externe server, bijvoorbeeld `vim` (aanbevolen om automatisch te detecteren volgens `EDITOR`).",
"sftpRmrDirSummary": "Gebruik `rm -r` om een map te verwijderen in SFTP.", "sftpRmrDirSummary": "Gebruik `rm -r` om een map te verwijderen in SFTP.",
"sftpSSHConnected": "SFTP Verbonden", "sftpSSHConnected": "SFTP Verbonden",
"sftpShowFoldersFirst": "Mappen eerst weergeven", "sftpShowFoldersFirst": "Mappen eerst weergeven",
@@ -270,6 +279,7 @@
"sshTip": "Deze functie bevindt zich momenteel in de experimentele fase.\n\nMeld alstublieft bugs op {url} of sluit je aan bij onze ontwikkeling.", "sshTip": "Deze functie bevindt zich momenteel in de experimentele fase.\n\nMeld alstublieft bugs op {url} of sluit je aan bij onze ontwikkeling.",
"sshVirtualKeyAutoOff": "Automatisch schakelen van virtuele toetsen", "sshVirtualKeyAutoOff": "Automatisch schakelen van virtuele toetsen",
"start": "Starten", "start": "Starten",
"stat": "Statistieken",
"stats": "Statistieken", "stats": "Statistieken",
"stop": "Stoppen", "stop": "Stoppen",
"stopped": "Gestopt", "stopped": "Gestopt",
@@ -296,7 +306,7 @@
"total": "Totaal", "total": "Totaal",
"traffic": "Verkeer", "traffic": "Verkeer",
"trySudo": "Probeer sudo te gebruiken", "trySudo": "Probeer sudo te gebruiken",
"ttl": "ttl", "ttl": "TTL",
"unknown": "Onbekend", "unknown": "Onbekend",
"unknownError": "Onbekende fout", "unknownError": "Onbekende fout",
"unkownConvertMode": "Onbekende conversiemodus", "unkownConvertMode": "Onbekende conversiemodus",
@@ -332,5 +342,6 @@
"willTakEeffectImmediately": "Zal onmiddellijk van kracht worden", "willTakEeffectImmediately": "Zal onmiddellijk van kracht worden",
"wolTip": "Na het configureren van WOL (Wake-on-LAN), wordt elke keer dat de server wordt verbonden een WOL-verzoek verzonden.", "wolTip": "Na het configureren van WOL (Wake-on-LAN), wordt elke keer dat de server wordt verbonden een WOL-verzoek verzonden.",
"write": "Schrijven", "write": "Schrijven",
"writeScriptFailTip": "Het schrijven naar het script is mislukt, mogelijk door gebrek aan rechten of omdat de map niet bestaat." "writeScriptFailTip": "Het schrijven naar het script is mislukt, mogelijk door gebrek aan rechten of omdat de map niet bestaat.",
"writeScriptTip": "Na het verbinden met de server wordt een script geschreven naar ~/.config/server_box om de systeemstatus te monitoren. U kunt de inhoud van het script controleren."
} }

Some files were not shown because too many files have changed in this diff Show More