opt.: l10n & fix: write script (#514)

This commit is contained in:
lollipopkit🏳️‍⚧️
2024-08-03 22:44:21 +08:00
committed by GitHub
parent 610f46da0d
commit 9db04a60c2
55 changed files with 686 additions and 2201 deletions

View File

@@ -3,7 +3,6 @@ import 'package:fl_lib/fl_lib.dart';
import 'package:fl_lib/l10n/gen_l10n/lib_l10n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:locale_names/locale_names.dart';
import 'package:server_box/core/extension/context/locale.dart';
import 'package:server_box/data/res/build_data.dart';
import 'package:server_box/data/res/rebuild.dart';

View File

@@ -1,3 +1,4 @@
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
import 'package:server_box/core/extension/context/locale.dart';
@@ -21,46 +22,27 @@ enum ContainerMenu {
terminal,
//stats,
];
} else {
}
return [start, rm, logs];
}
}
IconData get icon {
switch (this) {
case ContainerMenu.start:
return Icons.play_arrow;
case ContainerMenu.stop:
return Icons.stop;
case ContainerMenu.restart:
return Icons.restart_alt;
case ContainerMenu.rm:
return Icons.delete;
case ContainerMenu.logs:
return Icons.logo_dev;
case ContainerMenu.terminal:
return Icons.terminal;
// case DockerMenuType.stats:
// return Icons.bar_chart;
}
}
IconData get icon => switch (this) {
ContainerMenu.start => Icons.play_arrow,
ContainerMenu.stop => Icons.stop,
ContainerMenu.restart => Icons.restart_alt,
ContainerMenu.rm => Icons.delete,
ContainerMenu.logs => Icons.logo_dev,
ContainerMenu.terminal => Icons.terminal,
// DockerMenuType.stats => Icons.bar_chart,
};
String get toStr {
switch (this) {
case ContainerMenu.start:
return l10n.start;
case ContainerMenu.stop:
return l10n.stop;
case ContainerMenu.restart:
return l10n.restart;
case ContainerMenu.rm:
return l10n.delete;
case ContainerMenu.logs:
return l10n.log;
case ContainerMenu.terminal:
return l10n.terminal;
// case DockerMenuType.stats:
// return s.stats;
}
}
String get toStr => switch (this) {
ContainerMenu.start => l10n.start,
ContainerMenu.stop => l10n.stop,
ContainerMenu.restart => l10n.restart,
ContainerMenu.rm => libL10n.delete,
ContainerMenu.logs => libL10n.log,
ContainerMenu.terminal => l10n.terminal,
// DockerMenuType.stats => s.stats,
};
}

View File

@@ -1,3 +1,4 @@
import 'package:fl_lib/fl_lib.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:server_box/core/extension/context/locale.dart';
import 'package:server_box/data/model/server/server.dart';
@@ -14,27 +15,17 @@ enum NetViewType {
@HiveField(2)
traffic;
NetViewType get next {
switch (this) {
case conn:
return speed;
case speed:
return traffic;
case traffic:
return conn;
}
}
NetViewType get next => switch (this) {
conn => speed,
speed => traffic,
traffic => conn,
};
String get toStr {
switch (this) {
case NetViewType.conn:
return l10n.conn;
case NetViewType.traffic:
return l10n.traffic;
case NetViewType.speed:
return l10n.speed;
}
}
String get toStr => switch (this) {
NetViewType.conn => l10n.conn,
NetViewType.traffic => l10n.traffic,
NetViewType.speed => l10n.speed,
};
(String, String) build(ServerStatus ss) {
final ignoreLocal = Stores.setting.ignoreLocalNet.fetch();
@@ -42,7 +33,7 @@ enum NetViewType {
case NetViewType.conn:
return (
'${l10n.conn}:\n${ss.tcp.maxConn}',
'${l10n.failed}:\n${ss.tcp.fail}',
'${libL10n.fail}:\n${ss.tcp.fail}',
);
case NetViewType.speed:
if (ignoreLocal) {
@@ -69,25 +60,15 @@ enum NetViewType {
}
}
int toJson() {
switch (this) {
case NetViewType.conn:
return 0;
case NetViewType.speed:
return 1;
case NetViewType.traffic:
return 2;
}
}
int toJson() => switch (this) {
NetViewType.conn => 0,
NetViewType.speed => 1,
NetViewType.traffic => 2,
};
static NetViewType fromJson(int json) {
switch (json) {
case 0:
return NetViewType.conn;
case 2:
return NetViewType.traffic;
default:
return NetViewType.speed;
}
}
static NetViewType fromJson(int json) => switch (json) {
0 => NetViewType.conn,
1 => NetViewType.speed,
_ => NetViewType.traffic,
};
}

View File

@@ -19,14 +19,40 @@ enum ShellFunc {
/// srvboxm -> ServerBox Mobile
static const scriptFile = 'srvboxm_v${BuildData.script}.sh';
static const scriptDir = '~/.config/server_box';
static const scriptPath = '$scriptDir/$scriptFile';
static const scriptDirHome = '~/.config/server_box';
static const scriptDirTmp = '/tmp/server_box';
static const String installShellCmd = """
static final _scriptDirMap = <String, String>{};
/// Get the script directory for the given [id].
///
/// Default is [scriptDirTmp]/[scriptFile], if this path is not accessible,
/// it will be changed to [scriptDirHome]/[scriptFile].
static String getScriptDir(String id) {
return _scriptDirMap.putIfAbsent(id, () {
return scriptDirTmp;
});
}
static void switchScriptDir(String id) => switch (_scriptDirMap[id]) {
scriptDirTmp => _scriptDirMap[id] = scriptDirHome,
scriptDirHome => _scriptDirMap[id] = scriptDirTmp,
_ => _scriptDirMap[id] = scriptDirHome,
};
static String getScriptPath(String id) {
return '${getScriptDir(id)}/$scriptFile';
}
static String getInstallShellCmd(String id) {
final scriptDir = getScriptDir(id);
final scriptPath = '$scriptDir/$scriptFile';
return """
mkdir -p $scriptDir
cat > $scriptPath
chmod 744 $scriptPath
""";
}
String get flag => switch (this) {
ShellFunc.process => 'p',
@@ -37,7 +63,7 @@ chmod 744 $scriptPath
// ShellFunc.docker=> 'd',
};
String get exec => 'sh $scriptPath -$flag';
String exec(String id) => 'sh ${getScriptPath(id)} -$flag';
String get name {
switch (this) {

View File

@@ -1,5 +1,4 @@
import 'package:fl_lib/fl_lib.dart';
import 'package:server_box/core/extension/context/locale.dart';
final class SensorAdaptor {
final String raw;
@@ -37,7 +36,7 @@ final class SensorItem {
String get toMarkdown {
final sb = StringBuffer();
sb.writeln('| ${l10n.name} | ${l10n.content} |');
sb.writeln('| ${libL10n.name} | ${libL10n.content} |');
sb.writeln('| --- | --- |');
for (final entry in details.entries) {
sb.writeln('| ${entry.key} | ${entry.value} |');
@@ -80,9 +79,7 @@ final class SensorItem {
for (var idx = 2; idx < len; idx++) {
final part = sensorLines[idx];
final detailParts = part.split(':');
if (detailParts.length < 2) {
continue;
}
if (detailParts.length < 2) continue;
final key = detailParts[0].trim();
final value = detailParts[1].trim();
details[key] = value;

View File

@@ -1,8 +1,7 @@
import 'package:dartssh2/dartssh2.dart';
import 'package:fl_lib/fl_lib.dart';
import 'package:server_box/core/extension/context/locale.dart';
import 'package:server_box/data/model/app/error.dart';
import 'package:server_box/data/model/app/shell_func.dart';
import 'package:server_box/data/model/app/tag_pickable.dart';
import 'package:server_box/data/model/server/battery.dart';
import 'package:server_box/data/model/server/conn.dart';
import 'package:server_box/data/model/server/cpu.dart';
@@ -15,10 +14,6 @@ import 'package:server_box/data/model/server/server_private_info.dart';
import 'package:server_box/data/model/server/system.dart';
import 'package:server_box/data/model/server/temp.dart';
import '../app/tag_pickable.dart';
part 'server.ext.dart';
class Server implements TagPickable {
ServerPrivateInfo spi;
ServerStatus status;

View File

@@ -1,58 +0,0 @@
part of 'server.dart';
extension ServerX on Server {
String getTopRightStr(ServerPrivateInfo spi) {
switch (conn) {
case ServerConn.disconnected:
return l10n.disconnected;
case ServerConn.finished:
// Highest priority of temperature display
final cmdTemp = () {
final val = status.customCmds['server_card_top_right'];
if (val == null) return null;
// This returned value is used on server card top right, so it should
// be a single line string.
return val.split('\n').lastOrNull;
}();
final temperatureVal = () {
// Second priority
final preferTempDev = spi.custom?.preferTempDev;
if (preferTempDev != null) {
final preferTemp = status.sensors
.firstWhereOrNull((e) => e.device == preferTempDev)
?.summary
?.split(' ')
.firstOrNull;
if (preferTemp != null) {
return double.tryParse(preferTemp.replaceFirst('°C', ''));
}
}
// Last priority
final temp = status.temps.first;
if (temp != null) {
return temp;
}
return null;
}();
final upTime = status.more[StatusCmdType.uptime];
final items = [
cmdTemp ??
(temperatureVal != null
? '${temperatureVal.toStringAsFixed(1)}°C'
: null),
upTime
];
final str = items.where((e) => e != null && e.isNotEmpty).join(' | ');
if (str.isEmpty) return l10n.noResult;
return str;
case ServerConn.loading:
return l10n.serverTabLoading;
case ServerConn.connected:
return l10n.connected;
case ServerConn.connecting:
return l10n.serverTabConnecting;
case ServerConn.failed:
return status.err != null ? l10n.viewErr : l10n.serverTabFailed;
}
}
}

View File

@@ -301,29 +301,37 @@ class ServerProvider extends ChangeNotifier {
final scriptRaw = ShellFunc.allScript(spi.custom?.cmds).uint8List;
try {
await s.client!.runForOutput(
ShellFunc.installShellCmd,
final writeScriptResult = await s.client!.runForOutput(
ShellFunc.getInstallShellCmd(spi.id),
action: (session) async {
session.stdin.add(scriptRaw);
session.stdin.close();
},
);
if (writeScriptResult.isNotEmpty) {
ShellFunc.switchScriptDir(spi.id);
throw String.fromCharCodes(writeScriptResult);
}
} on SSHAuthAbortError catch (e) {
TryLimiter.inc(sid);
s.status.err = SSHErr(type: SSHErrType.auth, message: e.toString());
final err = SSHErr(type: SSHErrType.auth, message: e.toString());
s.status.err = err;
Loggers.app.warning(err);
_setServerState(s, ServerConn.failed);
return;
} on SSHAuthFailError catch (e) {
TryLimiter.inc(sid);
s.status.err = SSHErr(type: SSHErrType.auth, message: e.toString());
final err = SSHErr(type: SSHErrType.auth, message: e.toString());
s.status.err = err;
Loggers.app.warning(err);
_setServerState(s, ServerConn.failed);
return;
} catch (e) {
final err = e.toString();
TryLimiter.inc(sid);
s.status.err = SSHErr(type: SSHErrType.writeScript, message: err);
final err = SSHErr(type: SSHErrType.writeScript, message: e.toString());
s.status.err = err;
Loggers.app.warning(err);
_setServerState(s, ServerConn.failed);
Loggers.app.warning('Write script to ${spi.name} by shell', err);
}
}
@@ -340,7 +348,7 @@ class ServerProvider extends ChangeNotifier {
String? raw;
try {
raw = await s.client?.run(ShellFunc.status.exec).string;
raw = await s.client?.run(ShellFunc.status.exec(spi.id)).string;
segments = raw?.split(ShellFunc.seperator).map((e) => e.trim()).toList();
if (raw == null || raw.isEmpty || segments == null || segments.isEmpty) {
if (Stores.setting.keepStatusWhenErr.fetch()) {

View File

@@ -92,7 +92,7 @@ final class _IntroPage extends StatelessWidget {
final selected = await ctx.showPickSingleDialog(
title: l10n.language,
items: AppLocalizations.supportedLocales,
name: (p0) => '${p0.nativeDisplayLanguage} (${p0.code})',
name: (p0) => p0.nativeName,
initial: _setting.locale.fetch().toLocale,
);
if (selected != null) {
@@ -101,7 +101,7 @@ final class _IntroPage extends StatelessWidget {
}
},
trailing: Text(
l10n.languageName,
ctx.localeNativeName,
style: const TextStyle(fontSize: 15, color: Colors.grey),
),
).cardx,

View File

@@ -3,81 +3,43 @@
"about": "Über",
"aboutThanks": "Vielen Dank an die folgenden Personen, die daran teilgenommen haben.\n",
"acceptBeta": "Akzeptieren Sie Testversion-Updates",
"add": "Neu",
"addAServer": "Server hinzufügen",
"addPrivateKey": "Private key hinzufügen",
"addSystemPrivateKeyTip": "Derzeit haben Sie keinen privaten Schlüssel, fügen Sie den Schlüssel hinzu, der mit dem System geliefert wird (~/.ssh/id_rsa)?",
"added2List": "Zur Aufgabenliste hinzugefügt",
"addr": "Adresse",
"all": "Alle",
"alreadyLastDir": "Bereits im letzten Verzeichnis.",
"askContinue": "{msg}. Weiter?",
"attention": "Achtung",
"authFailTip": "Authentifizierung fehlgeschlagen, bitte überprüfen Sie, ob das Passwort/Schlüssel/Host/Benutzer usw. falsch sind.",
"authRequired": "Autorisierung erforderlich",
"auto": "System folgen",
"autoBackupConflict": "Es kann nur eine automatische Sicherung gleichzeitig aktiviert werden.",
"autoCheckUpdate": "Aktualisierung automatisch prüfen",
"autoConnect": "Automatisch verbinden",
"autoRun": "Automatischer Start",
"autoUpdateHomeWidget": "Home-Widget automatisch aktualisieren",
"backup": "Backup",
"backupTip": "Das Backup wird nur einfach verschlüsselt.\nBitte bewahre die Datei sicher auf.",
"backupVersionNotMatch": "Die Backup-Version stimmt nicht überein.",
"battery": "Batterie",
"bgRun": "Hintergrundaktualisierung",
"bgRunTip": "Dieser Schalter bedeutet nur, dass die App versuchen wird, im Hintergrund zu laufen. Ob sie im Hintergrund laufen kann, hängt davon ab, ob die Berechtigungen aktiviert sind oder nicht. Bei nativem Android deaktivieren Sie bitte \"Batterieoptimierung\" in dieser App, und bei miui ändern Sie bitte die Energiesparrichtlinie auf \"Unbegrenzt\".",
"bioAuth": "Biozertifizierung",
"browser": "Browser",
"bulkImportServers": "Server im Batch importieren",
"canPullRefresh": "Danach: herunterziehen zum Aktualisieren",
"cancel": "Abbrechen",
"choose": "Auswählen",
"chooseFontFile": "Schriftart auswählen",
"choosePrivateKey": "Private key auswählen",
"clear": "Entfernen",
"clipboard": "Zwischenablage",
"close": "Schließen",
"cmd": "Command",
"cnKeyboardComp": "Kompatibilität mit chinesischem Android",
"cnKeyboardCompTip": "Wenn das Terminal ein sicheres Tastenfeld öffnet, können Sie es aktivieren.",
"collapseUI": "Zusammenbrechen",
"collapseUITip": "Ob lange Listen in der Benutzeroberfläche standardmäßig eingeklappt werden sollen oder nicht",
"conn": "Verbindung",
"connected": "in Verbindung gebracht",
"container": "Container",
"containerName": "Container Name",
"containerStatus": "Container Status",
"containerTrySudoTip": "Zum Beispiel: In der App ist der Benutzer auf aaa eingestellt, aber Docker ist unter dem Root-Benutzer installiert. In diesem Fall müssen Sie diese Option aktivieren",
"content": "Inhalt",
"convert": "Konvertieren",
"copy": "Kopieren",
"copyPath": "Pfad kopieren",
"cpuViewAsProgressTip": "Zeigen Sie die Auslastung jedes CPUs in einem Fortschrittsbalken-Stil an (alter Stil)",
"createFile": "Datei erstellen",
"createFolder": "Ordner erstellen",
"cursorType": "Cursor-Typ",
"customCmd": "Benutzerdefinierte Befehle",
"customCmdDocUrl": "https://github.com/lollipopkit/flutter_server_box/wiki#custom-commands",
"customCmdHint": "\"Befehlsname\": \"Befehl\"",
"dark": "Dunkel",
"day": "Tag",
"debug": "Debug",
"decode": "Decode",
"decompress": "Dekomprimieren",
"delete": "Löschen",
"deleteServers": "Batch-Löschung von Servern",
"deviceName": "Gerätename",
"dirEmpty": "Stelle sicher, dass der Ordner leer ist.",
"disabled": "Behinderte",
"disconnected": "Disconnected",
"disk": "Festplatte",
"diskIgnorePath": "Pfad für Datenträger ignorieren",
"displayCpuIndex": "Zeigen Sie den CPU-Index an",
"displayName": "Name anzeigen",
"dl2Local": "Datei \"{fileName}\" herunterladen?",
"doc": "Dokumentation",
"dockerEditHost": "DOCKER_HOST bearbeiten",
"dockerEmptyRunningItems": "Es gibt keine laufenden Container.\nDas könnte daran liegen:\n- Der Docker-Installationsbenutzer ist nicht mit dem in der App konfigurierten Benutzernamen identisch.\n- Die Umgebungsvariable DOCKER_HOST wurde nicht korrekt gelesen. Sie können sie ermitteln, indem Sie `echo $DOCKER_HOST` im Terminal ausführen.",
"dockerImagesFmt": "{count} Image(s)",
"dockerNotInstalled": "Docker ist nicht installiert",
@@ -85,40 +47,24 @@
"dockerStatusRunningFmt": "{count} Container aktiv",
"doubleColumnMode": "Doppelspaltiger Modus",
"doubleColumnTip": "Diese Option aktiviert nur die Funktion, ob sie tatsächlich aktiviert werden kann, hängt auch von der Breite des Geräts ab",
"download": "Download",
"edit": "Bearbeiten",
"editVirtKeys": "Virtuelle Tasten bearbeiten",
"editor": "Editor",
"editorHighlightTip": "Die Leistung der aktuellen Codehervorhebung ist schlechter und kann zur Verbesserung optional ausgeschaltet werden.",
"encode": "Encode",
"envVars": "Umgebungsvariable",
"error": "Fehler",
"exampleName": "Servername",
"experimentalFeature": "Experimentelles Feature",
"export": "Export",
"extraArgs": "Extra args",
"failed": "Failed",
"fallbackSshDest": "SSH-Fallback-Ziel",
"fdroidReleaseTip": "Wenn Sie diese App von F-Droid heruntergeladen haben, wird empfohlen, diese Option zu deaktivieren.",
"feedback": "Feedback",
"feedbackOnGithub": "Wenn du Fragen hast, stelle diese bitte auf Github.",
"fieldMustNotEmpty": "Die Eingabefelder dürfen nicht leer sein.",
"fileNotExist": "{file} existiert nicht",
"fileTooLarge": "Datei '{file}' ist zu groß {size}, max {sizeMax}",
"files": "Dateien",
"finished": "fertiggestellt",
"followSystem": "System verfolgen",
"font": "Schriftarten",
"fontSize": "Schriftgröße",
"forExample": "Zum Beispiel",
"force": "freiwillig",
"foundNUpdate": "Update {count} gefunden",
"fullScreen": "Vollbildmodus",
"fullScreenJitter": "Jitter im Vollbildmodus",
"fullScreenJitterHelp": "Einbrennen des Bildschirms verhindern",
"fullScreenTip": "Soll der Vollbildmodus aktiviert werden, wenn das Gerät in den Quermodus gedreht wird? Diese Option gilt nur für die Server-Registerkarte.",
"getPushTokenFailed": "Push-Token kann nicht abgerufen werden",
"gettingToken": "Getting token...",
"goBackQ": "Zurückkommen?",
"goto": "Pfad öffnen",
"hideTitleBar": "Titelleiste ausblenden",
@@ -126,40 +72,26 @@
"highlight": "Code highlight",
"homeWidgetUrlConfig": "Home-Widget-Link konfigurieren",
"host": "Host",
"hour": "Stunde",
"httpFailedWithCode": "Anfrage fehlgeschlagen, Statuscode: {code}",
"icloudSynced": "iCloud wird synchronisiert und einige Einstellungen erfordern möglicherweise einen Neustart der App, um wirksam zu werden.",
"ignoreCert": "Zertifikat ignorieren",
"image": "Image",
"imagesList": "Images",
"import": "Importieren",
"inAppUpdate": "Im App aktualisieren? Andernfalls mit einem Browser herunterladen.",
"init": "Initialisieren",
"inner": "Eingebaut",
"inputDomainHere": "Domain eingeben",
"install": "install",
"installDockerWithUrl": "Bitte installiere docker zuerst. https://docs.docker.com/engine/install",
"invalid": "Ungültig",
"invalidJson": "Ungültige JSON",
"invalidVersion": "Ungültige Version",
"invalidVersionHelp": "Bitte stelle sicher, dass Docker korrekt installiert ist oder dass du eine nicht selbstkompilierte Version verwendest. Wenn du die oben genannten Probleme nicht hast, melde bitte einen Fehler auf {url}.",
"isBusy": "Is busy now",
"jumpServer": "Server springen",
"keepForeground": "Stelle sicher, dass die App geöffnet bleibt.",
"keepStatusWhenErr": "Den letzten Serverstatus beibehalten",
"keepStatusWhenErrTip": "Nur im Fehlerfall während der Ausführung des Skripts",
"keyAuth": "Schlüsselauthentifzierung",
"language": "Sprache",
"languageName": "Deutsch",
"lastTry": "Letzter Versuch",
"launchPage": "Startseite",
"letterCache": "Buchstaben-Caching",
"letterCacheTip": "Empfohlen, zu deaktivieren, aber nach dem Deaktivieren können keine CJK-Zeichen eingegeben werden.",
"license": "Lizenzen",
"light": "Hell",
"loadingFiles": "Lädt Dateien...",
"location": "Standort",
"log": "Log",
"loss": "loss",
"madeWithLove": "Erstellt mit ❤️ von {myGithub}",
"manual": "Handbuch",
@@ -167,37 +99,23 @@
"maxRetryCount": "Anzahl an Verbindungsversuchen",
"maxRetryCountEqual0": "Unbegrenzte Verbindungsversuche zum Server",
"min": "min",
"minute": "Minute",
"mission": "Mission",
"more": "Mehr",
"moveOutServerFuncBtnsHelp": "Ein: kann unter jeder Karte auf der Registerkarte \"Server\" angezeigt werden. Aus: kann oben auf der Seite \"Serverdetails\" angezeigt werden.",
"ms": "ms",
"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.",
"needRestart": "App muss neugestartet werden",
"net": "Netzwerk",
"netViewType": "Netzwerkansicht Typ",
"newContainer": "Neuer Container",
"noClient": "Kein Client",
"noInterface": "Kein Interface",
"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.",
"noOptions": "Keine Optionen verfügbar",
"noPrivateKeyTip": "Der private Schlüssel existiert nicht, möglicherweise wurde er gelöscht oder es liegt ein Konfigurationsfehler vor.",
"noPromptAgain": "Nicht mehr nachfragen",
"noResult": "Kein Ergebnis",
"noSavedPrivateKey": "Keine gespeicherten Private Keys",
"noSavedSnippet": "Keine gespeicherten Snippets.",
"noServerAvailable": "Kein Server verfügbar.",
"noTask": "Nicht fragen",
"noUpdateAvailable": "Kein Update verfügbar",
"node": "Knoten",
"notAvailable": "Nicht verfügbar",
"notSelected": "Nicht ausgewählt",
"note": "Hinweis",
"nullToken": "Null token",
"ok": "OK",
"onServerDetailPage": "in Detailansicht des Servers",
"onlyOneLine": "Nur als eine Zeile anzeigen (scrollbar)",
"onlyWhenCoreBiggerThan8": "Wirksam nur, wenn die Anzahl der Kerne > 8 ist.",
@@ -209,7 +127,6 @@
"path": "Pfad",
"percentOfSize": "{percent}% von {size}",
"permission": "Berechtigungen",
"pickFile": "Datei wählen",
"pingAvg": "Avg:",
"pingInputIP": "Bitte gib eine Ziel-IP/Domain ein.",
"pingNoServer": "Kein Server zum Anpingen.\nBitte füge einen Server hinzu.",
@@ -217,8 +134,6 @@
"pkgUpgradeTip": "Bitte sichern Sie Ihr System vor dem Update.",
"platformNotSupportUpdate": "Die aktuelle Plattform unterstützt keine In-App-Updates.\nBitte kompiliere vom Quellcode und installiere sie.",
"plugInType": "Einfügetyp",
"plzEnterHost": "Bitte Host eingeben.",
"plzSelectKey": "Wähle einen Key.",
"port": "Port",
"preview": "Vorschau",
"primaryColorSeed": "Farbschema",
@@ -231,16 +146,11 @@
"pwd": "Passwort",
"read": "Lesen",
"reboot": "Neustart",
"rememberChoice": "Auswahl merken",
"rememberPwdInMem": "Passwort im Speicher behalten",
"rememberPwdInMemTip": "Für Container, Aufhängen usw.",
"rememberWindowSize": "Fenstergröße merken",
"remotePath": "Entfernte Pfade",
"rename": "Umbenennen",
"reportBugsOnGithubIssue": "Bitte Bugs auf {url} melden",
"restart": "Neustart",
"restore": "Wiederherstellen",
"restoreSuccess": "Wiederherstellung erfolgreich. App neustarten um Änderungen anzuwenden.",
"result": "Result",
"rotateAngel": "Rotationswinkel",
"route": "Routen",
@@ -255,12 +165,6 @@
"serverDetailOrder": "Reihenfolge der Widgets auf der Detailseite",
"serverFuncBtns": "Server-Funktionsschaltflächen",
"serverOrder": "Server-Bestellung",
"serverTabConnecting": "Verbinden...",
"serverTabEmpty": "Keine Server vorhanden.",
"serverTabFailed": "Fehlgeschlagen",
"serverTabLoading": "Lädt...",
"serverTabPlzSave": "Bitte 'speichere' diesen privaten Schlüssel erneut.",
"serverTabUnkown": "Unbekannter Status",
"setting": "Einstellungen",
"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).",
@@ -307,7 +211,6 @@
"trySudo": "Versuche es mit sudo",
"ttl": "TTL",
"unknown": "Unbekannt",
"unknownError": "Unbekannter Fehler",
"unkownConvertMode": "Unbekannter Konvertierungsmodus",
"update": "Update",
"updateAll": "Alle aktualisieren",
@@ -318,13 +221,11 @@
"upload": "Hochladen",
"upsideDown": "Upside Down",
"uptime": "Betriebszeit",
"urlOrJson": "URL oder JSON",
"useCdn": "Verwenden von CDN",
"useCdnTip": "Nicht-chinesischen Benutzern wird die Verwendung eines CDN empfohlen. Möchten Sie es verwenden?",
"useNoPwd": "Es wird kein Passwort verwendet",
"usePodmanByDefault": "Standardmäßige Verwendung von Podman",
"used": "Gebraucht",
"user": "Benutzer",
"versionHaveUpdate": "Gefunden: v1.0.{build}, klicke zum Aktualisieren",
"versionUnknownUpdate": "Aktuell: v1.0.{build}. Klicken Sie hier, um nach Updates zu suchen",
"versionUpdated": "v1.0.{build} ist bereits die neueste Version",
@@ -338,7 +239,6 @@
"watchNotPaired": "Keine gekoppelte Apple Watch",
"webdavSettingEmpty": "Webdav-Einstellungen sind leer",
"whenOpenApp": "Beim Öffnen der App",
"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.",
"write": "Schreiben",
"writeScriptFailTip": "Das Schreiben des Skripts ist fehlgeschlagen, möglicherweise aufgrund fehlender Berechtigungen oder das Verzeichnis existiert nicht.",

View File

@@ -3,81 +3,43 @@
"about": "About",
"aboutThanks": "Thanks to the following people who participated in.",
"acceptBeta": "Accept beta version updates",
"add": "Add",
"addAServer": "add a server",
"addPrivateKey": "Add private key",
"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",
"addr": "Address",
"all": "All",
"alreadyLastDir": "Already in last directory.",
"askContinue": "{msg}. Continue?",
"attention": "Attention",
"authFailTip": "Authentication failed, please check whether credentials are correct",
"authRequired": "Auth required",
"auto": "Auto",
"autoBackupConflict": "Only one automatic backup can be turned on at the same time.",
"autoCheckUpdate": "Automatic update check",
"autoConnect": "Auto connect",
"autoRun": "Auto run",
"autoUpdateHomeWidget": "Automatic home widget update",
"backup": "Backup",
"backupTip": "The exported data is weakly encrypted. \nPlease keep it safe.",
"backupVersionNotMatch": "Backup version is not match.",
"battery": "Battery",
"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 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",
"browser": "Browser",
"bulkImportServers": "Batch import servers",
"canPullRefresh": "You can pull to refresh.",
"cancel": "Cancel",
"choose": "Choose",
"chooseFontFile": "Choose a font file",
"choosePrivateKey": "Choose private key",
"clear": "Clear",
"clipboard": "Clipboard",
"close": "Close",
"cmd": "Command",
"cnKeyboardComp": "Compatibility with Chinese Android",
"cnKeyboardCompTip": "If the terminal pops up a secure keyboard, you can enable it.",
"collapseUI": "Collapse",
"collapseUITip": "Whether to collapse long lists present in the UI by default",
"conn": "Connection",
"connected": "Connected",
"container": "Container",
"containerName": "Container name",
"containerStatus": "Container status",
"containerTrySudoTip": "For example: In the app, the user is set to aaa, but Docker is installed under the root user. In this case, you need to enable this option.",
"content": "Content",
"convert": "Convert",
"copy": "Copy",
"copyPath": "Copy path",
"cpuViewAsProgressTip": "Display the usage of each CPU in a progress bar style (old style)",
"createFile": "Create file",
"createFolder": "Create folder",
"cursorType": "Cursor type",
"customCmd": "Custom commands",
"customCmdDocUrl": "https://github.com/lollipopkit/flutter_server_box/wiki#custom-commands",
"customCmdHint": "\"Command Name\": \"Command\"",
"dark": "Dark",
"day": "Day",
"debug": "Debug",
"decode": "Decode",
"decompress": "Decompress",
"delete": "Delete",
"deleteServers": "Batch delete servers",
"deviceName": "Device name",
"dirEmpty": "Make sure the folder is empty.",
"disabled": "Disabled",
"disconnected": "Disconnected",
"disk": "Disk",
"diskIgnorePath": "Ignore path for disk",
"displayCpuIndex": "Display CPU index",
"displayName": "Display name",
"dl2Local": "Download {fileName} to local?",
"doc": "Documentation",
"dockerEditHost": "Edit DOCKER_HOST",
"dockerEmptyRunningItems": "There are no running containers.\nThis could be because:\n- The Docker installation user is not the same as the username configured within the App.\n- The environment variable DOCKER_HOST was not read correctly. You can get it by running `echo $DOCKER_HOST` in the terminal.",
"dockerImagesFmt": "{count} images",
"dockerNotInstalled": "Docker not installed",
@@ -85,40 +47,24 @@
"dockerStatusRunningFmt": "{count} container running.",
"doubleColumnMode": "Double column mode",
"doubleColumnTip": "This option only enables the feature, whether it can actually be enabled depends on the width of the device",
"download": "Download",
"edit": "Edit",
"editVirtKeys": "Edit virtual keys",
"editor": "Editor",
"editorHighlightTip": "The current code highlighting performance is not ideal and can be optionally turned off to improve.",
"encode": "Encode",
"envVars": "Environment variable",
"error": "Error",
"exampleName": "Example name",
"experimentalFeature": "Experimental feature",
"export": "Export",
"extraArgs": "Extra arguments",
"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",
"feedbackOnGithub": "If you have any questions, please create issues on Github.",
"fieldMustNotEmpty": "These fields must not be empty.",
"fileNotExist": "{file} not exist",
"fileTooLarge": "File '{file}' too large {size}, max {sizeMax}",
"files": "Files",
"finished": "Finished",
"followSystem": "Follow system",
"font": "Font",
"fontSize": "Font size",
"forExample": "For example",
"force": "Force",
"foundNUpdate": "Found {count} update",
"fullScreen": "Full screen mode",
"fullScreenJitter": "Full screen jitter",
"fullScreenJitterHelp": "To avoid screen burn-in",
"fullScreenTip": "Should full-screen mode be enabled when the device is rotated to landscape mode? This option only applies to the server tab.",
"getPushTokenFailed": "Can't fetch push token",
"gettingToken": "Getting token...",
"goBackQ": "Go back?",
"goto": "Go to",
"hideTitleBar": "Hide title bar",
@@ -126,40 +72,26 @@
"highlight": "Code highlighting",
"homeWidgetUrlConfig": "Config home widget url",
"host": "Host",
"hour": "Hour",
"httpFailedWithCode": "request failed, status code: {code}",
"icloudSynced": "iCloud wird synchronisiert und einige Einstellungen erfordern möglicherweise einen Neustart der App, um wirksam zu werden.",
"ignoreCert": "Ignore certificate",
"image": "Image",
"imagesList": "Images list",
"import": "Import",
"inAppUpdate": "Update within the app? Otherwise, download using a browser.",
"init": "Initialize",
"inner": "Inner",
"inputDomainHere": "Input Domain here",
"install": "install",
"installDockerWithUrl": "Please https://docs.docker.com/engine/install docker first.",
"invalid": "Invalid",
"invalidJson": "Invalid JSON",
"invalidVersion": "Invalid version",
"invalidVersionHelp": "Please make sure that docker is installed correctly, or that you are using a non-self-compiled version. If you don't have the above issues, please submit an issue on {url}.",
"isBusy": "Is busy now",
"jumpServer": "Jump server",
"keepForeground": "Keep app foreground!",
"keepStatusWhenErr": "Preserve the last server state",
"keepStatusWhenErrTip": "Only in the event of an error during script execution",
"keyAuth": "Key Auth",
"language": "Language",
"languageName": "English",
"lastTry": "Last try",
"launchPage": "Launch page",
"letterCache": "Letter caching",
"letterCacheTip": "Recommended to disable, but after disabling, it will be impossible to input CJK characters.",
"license": "License",
"light": "Light",
"loadingFiles": "Loading files...",
"location": "Location",
"log": "Log",
"loss": "loss",
"madeWithLove": "Made with ❤️ by {myGithub}",
"manual": "Manual",
@@ -167,37 +99,23 @@
"maxRetryCount": "Number of server reconnections",
"maxRetryCountEqual0": "Will retry again and again.",
"min": "min",
"minute": "Minute",
"mission": "Mission",
"more": "More",
"moveOutServerFuncBtnsHelp": "On: can be displayed below each card on the Server Tab page. Off: can be displayed at the top of the Server Details page.",
"ms": "ms",
"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.",
"needRestart": "App needs to be restarted",
"net": "Network",
"netViewType": "Network view type",
"newContainer": "New container",
"noClient": "No client",
"noInterface": "No interface",
"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.",
"noOptions": "No options",
"noPrivateKeyTip": "The private key does not exist, it may have been deleted or there is a configuration error.",
"noPromptAgain": "Do not prompt again",
"noResult": "No result",
"noSavedPrivateKey": "No saved private keys.",
"noSavedSnippet": "No saved snippets.",
"noServerAvailable": "No server available.",
"noTask": "No task",
"noUpdateAvailable": "No update available",
"node": "Node",
"notAvailable": "Unavailable",
"notSelected": "Not selected",
"note": "Note",
"nullToken": "Null token",
"ok": "OK",
"onServerDetailPage": "On server detail page",
"onlyOneLine": "Only display as one line (scrollable)",
"onlyWhenCoreBiggerThan8": "Works only when the number of cores is greater than 8",
@@ -209,7 +127,6 @@
"path": "Path",
"percentOfSize": "{percent}% of {size}",
"permission": "Permissions",
"pickFile": "Pick file",
"pingAvg": "Avg:",
"pingInputIP": "Please input a target IP / domain.",
"pingNoServer": "No server to ping.\nPlease add a server in server tab.",
@@ -217,8 +134,6 @@
"pkgUpgradeTip": "Please backup your system before updating.",
"platformNotSupportUpdate": "Current platform does not support in-app update.\nPlease build from source and install it.",
"plugInType": "Insertion Type",
"plzEnterHost": "Please enter host.",
"plzSelectKey": "Please select a key.",
"port": "Port",
"preview": "Preview",
"primaryColorSeed": "Primary color seed",
@@ -231,16 +146,11 @@
"pwd": "Password",
"read": "Read",
"reboot": "Reboot",
"rememberChoice": "Remember the selection",
"rememberPwdInMem": "Remember password in memory",
"rememberPwdInMemTip": "Used for containers, suspending, etc.",
"rememberWindowSize": "Remember window size",
"remotePath": "Remote path",
"rename": "Rename",
"reportBugsOnGithubIssue": "Please report bugs on {url}",
"restart": "Restart",
"restore": "Restore",
"restoreSuccess": "Restore success. Restart app to apply.",
"result": "Result",
"rotateAngel": "Rotation angle",
"route": "Routing",
@@ -255,12 +165,6 @@
"serverDetailOrder": "Detail page widget order",
"serverFuncBtns": "Server function buttons",
"serverOrder": "Server order",
"serverTabConnecting": "Connecting...",
"serverTabEmpty": "There is no server.\nClick the fab to add one.",
"serverTabFailed": "Failed",
"serverTabLoading": "Loading...",
"serverTabPlzSave": "Please 'save' this private key again.",
"serverTabUnkown": "Unknown state",
"setting": "Settings",
"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`).",
@@ -307,7 +211,6 @@
"trySudo": "Try using sudo",
"ttl": "TTL",
"unknown": "Unknown",
"unknownError": "Unknown error",
"unkownConvertMode": "Unknown conversion mode",
"update": "Update",
"updateAll": "Update all",
@@ -318,13 +221,11 @@
"upload": "Upload",
"upsideDown": "Upside Down",
"uptime": "Uptime",
"urlOrJson": "URL or JSON",
"useCdn": "Using CDN",
"useCdnTip": "Non-Chinese users are recommended to use CDN. Would you like to use it?",
"useNoPwd": "No password will be used",
"usePodmanByDefault": "Use Podman by default",
"used": "Used",
"user": "User",
"versionHaveUpdate": "Found: v1.0.{build}, click to update",
"versionUnknownUpdate": "Current: v1.0.{build}, click to check updates",
"versionUpdated": "Current: v1.0.{build}, is up to date",
@@ -338,7 +239,6 @@
"watchNotPaired": "No paired Apple Watch",
"webdavSettingEmpty": "WebDav setting is empty",
"whenOpenApp": "When opening the app",
"willTakEeffectImmediately": "Will take effect immediately",
"wolTip": "After configuring WOL (Wake-on-LAN), a WOL request is sent each time the server is connected.",
"write": "Write",
"writeScriptFailTip": "Writing to the script failed, possibly due to lack of permissions or the directory does not exist.",

View File

@@ -3,81 +3,43 @@
"about": "Acerca de",
"aboutThanks": "Gracias a los siguientes participantes.",
"acceptBeta": "Aceptar actualizaciones de la versión de prueba",
"add": "Añadir",
"addAServer": "Agregar un servidor",
"addPrivateKey": "Agregar una llave privada",
"addSystemPrivateKeyTip": "Actualmente no hay ninguna llave privada, ¿quieres agregar la que viene por defecto en el sistema (~/.ssh/id_rsa)?",
"added2List": "Añadido a la lista de tareas",
"addr": "Dirección",
"all": "Todos",
"alreadyLastDir": "Ya estás en el directorio superior",
"askContinue": "{msg}, ¿continuar?",
"attention": "Atención",
"authFailTip": "La autenticación ha fallado, por favor verifica si la contraseña/llave/host/usuario, etc., son incorrectos.",
"authRequired": "Autenticación requerida",
"auto": "Automático",
"autoBackupConflict": "Solo se puede activar una copia de seguridad automática a la vez",
"autoCheckUpdate": "Verificación automática de actualizaciones",
"autoConnect": "Conexión automática",
"autoRun": "Ejecución automática",
"autoUpdateHomeWidget": "Actualizar automáticamente el widget del escritorio",
"backup": "Respaldo",
"backupTip": "Los datos exportados solo están encriptados de manera básica, por favor guárdalos en un lugar seguro.",
"backupVersionNotMatch": "La versión de la copia de seguridad no coincide, no se puede restaurar",
"battery": "Batería",
"bgRun": "Ejecución en segundo plano",
"bgRunTip": "Este interruptor solo indica que la aplicación intentará correr en segundo plano, si puede hacerlo o no depende de si tiene el permiso correspondiente. En Android puro, por favor desactiva la “optimización de batería” para esta app, en MIUI por favor cambia la estrategia de ahorro de energía a “Sin restricciones”.",
"bioAuth": "Autenticación biométrica",
"browser": "Navegador",
"bulkImportServers": "Importar servidores en masa",
"canPullRefresh": "Se puede deslizar hacia abajo para refrescar",
"cancel": "Cancelar",
"choose": "Elegir",
"chooseFontFile": "Seleccionar archivo de fuente",
"choosePrivateKey": "Elegir llave privada",
"clear": "Limpiar",
"clipboard": "Portapapeles",
"close": "Cerrar",
"cmd": "Comando",
"cnKeyboardComp": "Compatibilidad con Android chino",
"cnKeyboardCompTip": "Si el terminal muestra un teclado seguro, puedes activarlo.",
"collapseUI": "Colapsar",
"collapseUITip": "¿Colapsar por defecto las listas largas en la UI?",
"conn": "Conectar",
"connected": "Conectado",
"container": "Contenedor",
"containerName": "Nombre del contenedor",
"containerStatus": "Estado del contenedor",
"containerTrySudoTip": "Por ejemplo: si configuras el usuario dentro de la app como aaa, pero Docker está instalado bajo el usuario root, entonces necesitarás habilitar esta opción",
"content": "Contenido",
"convert": "Convertir",
"copy": "Copiar",
"copyPath": "Copiar ruta",
"cpuViewAsProgressTip": "Muestre la tasa de uso de cada CPU en estilo de barra de progreso (estilo antiguo)",
"createFile": "Crear archivo",
"createFolder": "Crear carpeta",
"cursorType": "Tipo de cursor",
"customCmd": "Comandos personalizados",
"customCmdDocUrl": "https://github.com/lollipopkit/flutter_server_box/wiki#custom-commands",
"customCmdHint": "\"Nombre del comando\": \"Comando\"",
"dark": "Oscuro",
"day": "Día",
"debug": "Depurar",
"decode": "Decodificar",
"decompress": "Descomprimir",
"delete": "Eliminar",
"deleteServers": "Eliminar servidores en lote",
"deviceName": "Nombre del dispositivo",
"dirEmpty": "Asegúrate de que el directorio esté vacío",
"disabled": "Deshabilitado",
"disconnected": "Desconectado",
"disk": "Disco",
"diskIgnorePath": "Rutas de disco ignoradas",
"displayCpuIndex": "Muestre el índice de CPU",
"displayName": "Nombre a mostrar",
"dl2Local": "¿Descargar {fileName} a local?",
"doc": "Documentación",
"dockerEditHost": "Editar DOCKER_HOST",
"dockerEmptyRunningItems": "No hay contenedores en ejecución.\nEsto podría deberse a que:\n- El usuario con el que se instaló Docker es diferente al configurado en la app\n- La variable de entorno DOCKER_HOST no se ha leído correctamente. Puedes obtenerla ejecutando `echo $DOCKER_HOST` en el terminal.",
"dockerImagesFmt": "Total de {count} imágenes",
"dockerNotInstalled": "Docker no está instalado",
@@ -85,40 +47,24 @@
"dockerStatusRunningFmt": "{count} contenedores en ejecución",
"doubleColumnMode": "Modo de doble columna",
"doubleColumnTip": "Esta opción solo habilita la función, si se puede activar o no depende del ancho del dispositivo",
"download": "Descargar",
"edit": "Editar",
"editVirtKeys": "Editar teclas virtuales",
"editor": "Editor",
"editorHighlightTip": "El rendimiento del resaltado de código es bastante pobre actualmente, puedes elegir desactivarlo para mejorar.",
"encode": "Codificar",
"envVars": "Variable de entorno",
"error": "Error",
"exampleName": "Ejemplo de nombre",
"experimentalFeature": "Función experimental",
"export": "Exportar",
"extraArgs": "Argumentos extra",
"failed": "Fallido",
"fallbackSshDest": "Destino SSH alternativo",
"fdroidReleaseTip": "Si descargaste esta aplicación desde F-Droid, se recomienda desactivar esta opción.",
"feedback": "Retroalimentación",
"feedbackOnGithub": "Si tienes algún problema, por favor informa en GitHub",
"fieldMustNotEmpty": "Estos campos no pueden estar vacíos.",
"fileNotExist": "{file} no existe",
"fileTooLarge": "El archivo '{file}' es demasiado grande '{size}', supera el {sizeMax}",
"files": "Archivos",
"finished": "Finalizado",
"followSystem": "Seguir al sistema",
"font": "Fuente",
"fontSize": "Tamaño de fuente",
"forExample": "Por ejemplo",
"force": "Forzar",
"foundNUpdate": "Encontradas {count} actualizaciones",
"fullScreen": "Modo pantalla completa",
"fullScreenJitter": "Temblores en modo pantalla completa",
"fullScreenJitterHelp": "Prevención de quemaduras de pantalla",
"fullScreenTip": "¿Debe habilitarse el modo de pantalla completa cuando el dispositivo se rote al modo horizontal? Esta opción solo se aplica a la pestaña del servidor.",
"getPushTokenFailed": "No se pudo obtener el token de notificación",
"gettingToken": "Obteniendo Token...",
"goBackQ": "¿Regresar?",
"goto": "Ir a",
"hideTitleBar": "Ocultar barra de título",
@@ -126,40 +72,26 @@
"highlight": "Resaltar código",
"homeWidgetUrlConfig": "Configuración de URL del widget de inicio",
"host": "Anfitrión",
"hour": "Hora",
"httpFailedWithCode": "Fallo en la solicitud, código de estado: {code}",
"icloudSynced": "iCloud sincronizado, algunos ajustes pueden requerir reiniciar para tomar efecto.",
"ignoreCert": "Ignorar certificado",
"image": "Imagen",
"imagesList": "Lista de imágenes",
"import": "Importar",
"inAppUpdate": "¿Actualizar dentro de la app? De lo contrario, descargar usando un navegador.",
"init": "Inicializar",
"inner": "Interno",
"inputDomainHere": "Introduce el dominio aquí",
"install": "Instalar",
"installDockerWithUrl": "Por favor instala Docker primero desde https://docs.docker.com/engine/install",
"invalid": "Inválido",
"invalidJson": "JSON inválido",
"invalidVersion": "Versión no soportada",
"invalidVersionHelp": "Por favor asegúrate de haber instalado Docker correctamente o que no estés usando una versión compilada por ti mismo. Si no tienes estos problemas, informa en {url}.",
"isBusy": "Está ocupado",
"jumpServer": "Servidor de salto",
"keepForeground": "¡Por favor, mantén la app en primer plano!",
"keepStatusWhenErr": "Mantener el estado anterior del servidor",
"keepStatusWhenErrTip": "Solo aplica cuando hay errores al ejecutar scripts",
"keyAuth": "Autenticación con llave",
"language": "Idioma",
"languageName": "Español",
"lastTry": "Último intento",
"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",
"light": "Claro",
"loadingFiles": "Cargando directorio...",
"location": "Ubicación",
"log": "Registro",
"loss": "Tasa de pérdida",
"madeWithLove": "Hecho con ❤️ por {myGithub}",
"manual": "Manual",
@@ -167,37 +99,23 @@
"maxRetryCount": "Número máximo de reintentos de conexión al servidor",
"maxRetryCountEqual0": "Reintentará infinitamente",
"min": "Mínimo",
"minute": "Minuto",
"mission": "Misión",
"more": "Más",
"moveOutServerFuncBtnsHelp": "Activado: se mostrará debajo de cada tarjeta en la página de servidores. Desactivado: se mostrará en la parte superior de los detalles del servidor.",
"ms": "milisegundos",
"name": "Nombre",
"needHomeDir": "Si eres usuario de Synology, [consulta aquí](https://kb.synology.com/DSM/tutorial/user_enable_home_service). Los usuarios de otros sistemas deben buscar cómo crear un directorio home.",
"needRestart": "Necesita reiniciar la app",
"net": "Red",
"netViewType": "Tipo de vista de red",
"newContainer": "Crear contenedor nuevo",
"noClient": "No hay conexión SSH",
"noInterface": "No hay interfaz disponible",
"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.",
"noOptions": "Sin opciones disponibles",
"noPrivateKeyTip": "La clave privada no existe, puede haber sido eliminada o hay un error de configuración.",
"noPromptAgain": "No volver a preguntar",
"noResult": "Sin resultados",
"noSavedPrivateKey": "No hay llaves privadas guardadas.",
"noSavedSnippet": "No hay fragmentos de código guardados.",
"noServerAvailable": "No hay servidores disponibles.",
"noTask": "Sin tareas",
"noUpdateAvailable": "No hay actualizaciones disponibles",
"node": "Nodo",
"notAvailable": "No disponible",
"notSelected": "No seleccionado",
"note": "Nota",
"nullToken": "Token nulo",
"ok": "Ok",
"onServerDetailPage": "En la página de detalles del servidor",
"onlyOneLine": "Mostrar solo en una línea (desplazable)",
"onlyWhenCoreBiggerThan8": "Efectivo solo cuando el número de núcleos > 8",
@@ -209,7 +127,6 @@
"path": "Ruta",
"percentOfSize": "El {percent}% de {size}",
"permission": "Permisos",
"pickFile": "Seleccionar archivo",
"pingAvg": "Promedio:",
"pingInputIP": "Por favor, introduce la IP de destino o el dominio",
"pingNoServer": "No hay servidores disponibles para hacer Ping\nPor favor, añade un servidor en la pestaña de servidores y vuelve a intentarlo",
@@ -217,8 +134,6 @@
"pkgUpgradeTip": "Realice una copia de seguridad de su sistema antes de actualizar.",
"platformNotSupportUpdate": "La plataforma actual no soporta actualizaciones, por favor instala manualmente la última versión del código fuente",
"plugInType": "Tipo de inserción",
"plzEnterHost": "Por favor, introduce el host",
"plzSelectKey": "Por favor, selecciona una llave privada",
"port": "Puerto",
"preview": "Vista previa",
"primaryColorSeed": "Semilla de color primario",
@@ -231,16 +146,11 @@
"pwd": "Contraseña",
"read": "Leer",
"reboot": "Reiniciar",
"rememberChoice": "Recordar la selección",
"rememberPwdInMem": "Recordar contraseña en la memoria",
"rememberPwdInMemTip": "Utilizado para contenedores, suspensión, etc.",
"rememberWindowSize": "Recordar el tamaño de la ventana",
"remotePath": "Ruta remota",
"rename": "Renombrar",
"reportBugsOnGithubIssue": "Por favor, informa los problemas en {url}",
"restart": "Reiniciar",
"restore": "Restaurar",
"restoreSuccess": "Restauración exitosa, necesitas reiniciar la App para aplicar cambios",
"result": "Resultado",
"rotateAngel": "Ángulo de rotación",
"route": "Enrutamiento",
@@ -255,12 +165,6 @@
"serverDetailOrder": "Orden de los componentes en la página de detalles del servidor",
"serverFuncBtns": "Botones de función del servidor",
"serverOrder": "Orden del servidor",
"serverTabConnecting": "Conectando...",
"serverTabEmpty": "No hay servidores por ahora.\nHaz clic en el botón de la esquina inferior derecha para añadir uno.",
"serverTabFailed": "Fallo",
"serverTabLoading": "Cargando...",
"serverTabPlzSave": "Por favor, guarda la llave privada nuevamente",
"serverTabUnkown": "Estado desconocido",
"setting": "Configuración",
"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`).",
@@ -307,7 +211,6 @@
"trySudo": "Intentar con sudo",
"ttl": "TTL",
"unknown": "Desconocido",
"unknownError": "Error desconocido",
"unkownConvertMode": "Modo de conversión desconocido",
"update": "Actualizar",
"updateAll": "Actualizar todo",
@@ -318,13 +221,11 @@
"upload": "Subir",
"upsideDown": "Invertir arriba por abajo",
"uptime": "Tiempo de actividad",
"urlOrJson": "URL o JSON",
"useCdn": "Usando CDN",
"useCdnTip": "Se recomienda a los usuarios no chinos utilizar CDN. ¿Le gustaría utilizarlo?",
"useNoPwd": "Se usará sin contraseña",
"usePodmanByDefault": "Usar Podman por defecto",
"used": "Usado",
"user": "Usuario",
"versionHaveUpdate": "Nueva versión encontrada: v1.0.{build}, haz clic para actualizar",
"versionUnknownUpdate": "Actual: v1.0.{build}, haz clic para verificar actualizaciones",
"versionUpdated": "Actual: v1.0.{build}, ya estás en la última versión",
@@ -338,7 +239,6 @@
"watchNotPaired": "No hay un Apple Watch emparejado",
"webdavSettingEmpty": "La configuración de Webdav está vacía",
"whenOpenApp": "Al abrir la App",
"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.",
"write": "Escribir",
"writeScriptFailTip": "La escritura en el script falló, posiblemente por falta de permisos o porque el directorio no existe.",

View File

@@ -3,81 +3,43 @@
"about": "À propos",
"aboutThanks": "Merci aux personnes suivantes qui ont participé.",
"acceptBeta": "Accepter les mises à jour de la version de test",
"add": "Ajouter",
"addAServer": "Ajouter un serveur",
"addPrivateKey": "Ajouter une clé privée",
"addSystemPrivateKeyTip": "Actuellement, vous n'avez aucune clé privée. Souhaitez-vous ajouter celle qui vient avec le système (~/.ssh/id_rsa) ?",
"added2List": "Ajouté à la liste des tâches",
"addr": "Adresse",
"all": "Tous",
"alreadyLastDir": "Déjà dans le dernier répertoire.",
"askContinue": "{msg}. Continuer ?",
"attention": "Attention",
"authFailTip": "Échec de l'authentification. Veuillez vérifier si le mot de passe/clé/hôte/utilisateur, etc., est incorrect.",
"authRequired": "Authentification requise",
"auto": "Automatique",
"autoBackupConflict": "Un seul sauvegarde automatique peut être activé en même temps.",
"autoCheckUpdate": "Vérification automatique des mises à jour",
"autoConnect": "Connexion automatique",
"autoRun": "Exécution automatique",
"autoUpdateHomeWidget": "Mise à jour automatique du widget d'accueil",
"backup": "Sauvegarde",
"backupTip": "Les données exportées sont simplement chiffrées. \nVeuillez les garder en sécurité.",
"backupVersionNotMatch": "La version de sauvegarde ne correspond pas.",
"battery": "Batterie",
"bgRun": "Exécution en arrière-plan",
"bgRunTip": "Cette option signifie seulement que le programme essaiera de s'exécuter en arrière-plan, que cela soit possible dépend de l'autorisation activée ou non. Pour Android natif, veuillez désactiver l'« Optimisation de la batterie » dans cette application, et pour MIUI, veuillez changer la politique d'économie d'énergie en « Illimité ».",
"bioAuth": "Authentification biométrique",
"browser": "Navigateur",
"bulkImportServers": "Importation groupée des serveurs",
"canPullRefresh": "Vous pouvez tirer pour rafraîchir.",
"cancel": "Annuler",
"choose": "Choisir",
"chooseFontFile": "Choisir un fichier de police",
"choosePrivateKey": "Choisir une clé privée",
"clear": "Effacer",
"clipboard": "Presse-papiers",
"close": "Fermer",
"cmd": "Commande",
"cnKeyboardComp": "Compatibilité avec Android chinois",
"cnKeyboardCompTip": "Si le terminal affiche un clavier sécurisé, vous pouvez l'activer.",
"collapseUI": "Réduire",
"collapseUITip": "Indique si les longues listes présentées dans l'interface utilisateur doivent être réduites par défaut.",
"conn": "Connexion",
"connected": "Connecté",
"container": "Conteneur",
"containerName": "Nom du conteneur",
"containerStatus": "État du conteneur",
"containerTrySudoTip": "Par exemple : Dans l'application, l'utilisateur est défini comme aaa, mais Docker est installé sous l'utilisateur root. Dans ce cas, vous devez activer cette option.",
"content": "Contenu",
"convert": "Convertir",
"copy": "Copier",
"copyPath": "Copier le chemin",
"cpuViewAsProgressTip": "Afficher le taux d'utilisation de chaque CPU sous forme de barre de progression (ancien style)",
"createFile": "Créer un fichier",
"createFolder": "Créer un dossier",
"cursorType": "Type de curseur",
"customCmd": "Commandes personnalisées",
"customCmdDocUrl": "https://github.com/lollipopkit/flutter_server_box/wiki#custom-commands",
"customCmdHint": "\"Nom de la commande\": \"Commande\"",
"dark": "Sombre",
"day": "Jour",
"debug": "Débogage",
"decode": "Décoder",
"decompress": "Décompresser",
"delete": "Supprimer",
"deleteServers": "Supprimer des serveurs en lot",
"deviceName": "Nom de l'appareil",
"dirEmpty": "Assurez-vous que le répertoire est vide.",
"disabled": "Désactivé",
"disconnected": "Déconnecté",
"disk": "Disque",
"diskIgnorePath": "Chemin à ignorer pour le disque",
"displayCpuIndex": "Afficher l'index CPU",
"displayName": "Nom d'affichage",
"dl2Local": "Télécharger {fileName} localement ?",
"doc": "Documentation",
"dockerEditHost": "Modifier DOCKER_HOST",
"dockerEmptyRunningItems": "Aucun conteneur en cours d'exécution.\nCela peut être dû à :\n- L'utilisateur d'installation de Docker n'est pas le même que celui configuré dans l'application.\n- La variable d'environnement DOCKER_HOST n'a pas été lue correctement. Vous pouvez l'obtenir en exécutant `echo $DOCKER_HOST` dans le terminal.",
"dockerImagesFmt": "{count} images",
"dockerNotInstalled": "Docker non installé",
@@ -85,40 +47,24 @@
"dockerStatusRunningFmt": "{count} conteneur en cours d'exécution.",
"doubleColumnMode": "Mode double colonne",
"doubleColumnTip": "Cette option n'active que la fonctionnalité, qu'elle puisse être activée dépend de la largeur de l'appareil.",
"download": "Télécharger",
"edit": "Éditer",
"editVirtKeys": "Modifier les touches virtuelles",
"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.",
"encode": "Encoder",
"envVars": "Variable denvironnement",
"error": "Erreur",
"exampleName": "Nom de l'exemple",
"experimentalFeature": "Fonctionnalité expérimentale",
"export": "Exporter",
"extraArgs": "Arguments supplémentaires",
"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",
"feedbackOnGithub": "Si vous avez des questions, veuillez donner votre avis sur Github.",
"fieldMustNotEmpty": "Ces champs ne doivent pas être vides.",
"fileNotExist": "{file} n'existe pas",
"fileTooLarge": "Fichier '{file}' trop volumineux {size}, max {sizeMax}",
"files": "Fichiers",
"finished": "Terminé",
"followSystem": "Suivre le système",
"font": "Police",
"fontSize": "Taille de la police",
"forExample": "Par exemple",
"force": "Forcer",
"foundNUpdate": "{count} mise à jour trouvée",
"fullScreen": "Mode plein écran",
"fullScreenJitter": "Secousse en plein écran",
"fullScreenJitterHelp": "Pour éviter les brûlures d'écran",
"fullScreenTip": "Le mode plein écran doit-il être activé lorsque l'appareil est orienté en mode paysage ? Cette option s'applique uniquement à l'onglet serveur.",
"getPushTokenFailed": "Impossible de récupérer le jeton de notification",
"gettingToken": "Récupération du jeton...",
"goBackQ": "Revenir en arrière ?",
"goto": "Aller à",
"hideTitleBar": "Masquer la barre de titre",
@@ -126,40 +72,26 @@
"highlight": "Mise en surbrillance du code",
"homeWidgetUrlConfig": "Configurer l'URL du widget d'accueil",
"host": "Hôte",
"hour": "Heure",
"httpFailedWithCode": "Échec de la requête, code d'état : {code}",
"icloudSynced": "iCloud est en cours de synchronisation et certains paramètres peuvent nécessiter un redémarrage de l'application pour prendre effet.",
"ignoreCert": "Ignorer le certificat",
"image": "Image",
"imagesList": "Liste des images",
"import": "Importer",
"inAppUpdate": "Mettre à jour dans l'application ? Sinon, téléchargez en utilisant un navigateur.",
"init": "Initialiser",
"inner": "Interne",
"inputDomainHere": "Saisissez le domaine ici",
"install": "Installer",
"installDockerWithUrl": "Veuillez d'abord installer docker depuis https://docs.docker.com/engine/install.",
"invalid": "Invalide",
"invalidJson": "JSON invalide",
"invalidVersion": "Version invalide",
"invalidVersionHelp": "Assurez-vous que docker est correctement installé, ou que vous utilisez une version non compilée par vous-même. Si vous n'avez pas les problèmes ci-dessus, veuillez soumettre un problème sur {url}.",
"isBusy": "Est occupé maintenant",
"jumpServer": "Aller au serveur",
"keepForeground": "Garder l'application en premier plan !",
"keepStatusWhenErr": "Conserver l'état du dernier serveur",
"keepStatusWhenErrTip": "Uniquement en cas d'erreur lors de l'exécution du script",
"keyAuth": "Authentification par clé",
"language": "Langue",
"languageName": "Français",
"lastTry": "Dernière tentative",
"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",
"light": "Clair",
"loadingFiles": "Chargement des fichiers...",
"location": "Emplacement",
"log": "Journal",
"loss": "Perte",
"madeWithLove": "Fabriqué avec ❤️ par {myGithub}",
"manual": "Manuel",
@@ -167,37 +99,23 @@
"maxRetryCount": "Nombre de reconnexions au serveur",
"maxRetryCountEqual0": "Il va réessayer encore et encore.",
"min": "min",
"minute": "Minute",
"mission": "Mission",
"more": "Plus",
"moveOutServerFuncBtnsHelp": "Activé : peut être affiché sous chaque carte sur la page de l'onglet Serveur. Désactivé : peut être affiché en haut de la page de détails du serveur.",
"ms": "ms",
"name": "Nom",
"needHomeDir": "Si vous êtes utilisateur Synology, [consultez ici](https://kb.synology.com/DSM/tutorial/user_enable_home_service). Les utilisateurs d'autres systèmes doivent rechercher comment créer un répertoire personnel.",
"needRestart": "Nécessite un redémarrage de l'application",
"net": "Réseau",
"netViewType": "Type de vue réseau",
"newContainer": "Nouveau conteneur",
"noClient": "Pas de client",
"noInterface": "Pas d'interface",
"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.",
"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.",
"noPromptAgain": "Ne pas demander à nouveau",
"noResult": "Pas de résultat",
"noSavedPrivateKey": "Aucune clé privée enregistrée.",
"noSavedSnippet": "Aucun extrait de code enregistré.",
"noServerAvailable": "Aucun serveur disponible.",
"noTask": "Pas de tâche",
"noUpdateAvailable": "Pas de mise à jour disponible",
"node": "Nœud",
"notAvailable": "Indisponible",
"notSelected": "Non sélectionné",
"note": "Note",
"nullToken": "Jeton nul",
"ok": "OK",
"onServerDetailPage": "Sur la page de détails du serveur",
"onlyOneLine": "Afficher uniquement en une seule ligne (défilement)",
"onlyWhenCoreBiggerThan8": "Fonctionne uniquement lorsque le nombre de cœurs est > 8",
@@ -209,7 +127,6 @@
"path": "Chemin",
"percentOfSize": "{percent}% de {size}",
"permission": "Permissions",
"pickFile": "Choisir un fichier",
"pingAvg": "Moy.:",
"pingInputIP": "Veuillez saisir une adresse IP / un domaine cible.",
"pingNoServer": "Aucun serveur à pinger.\nVeuillez ajouter un serveur dans l'onglet serveur.",
@@ -217,8 +134,6 @@
"pkgUpgradeTip": "Veuillez sauvegarder votre système avant de procéder à la mise à jour.",
"platformNotSupportUpdate": "La plateforme actuelle ne prend pas en charge la mise à jour dans l'application.\nVeuillez le compiler depuis les sources et l'installer.",
"plugInType": "Type d'insertion",
"plzEnterHost": "Veuillez saisir l'hôte.",
"plzSelectKey": "Veuillez sélectionner une clé.",
"port": "Port",
"preview": "Aperçu",
"primaryColorSeed": "Graine de couleur primaire",
@@ -231,16 +146,11 @@
"pwd": "Mot de passe",
"read": "Lire",
"reboot": "Redémarrer",
"rememberChoice": "Se souvenir du choix",
"rememberPwdInMem": "Mémoriser le mot de passe en mémoire",
"rememberPwdInMemTip": "Utilisé pour les conteneurs, la suspension, etc.",
"rememberWindowSize": "Se souvenir de la taille de la fenêtre",
"remotePath": "Chemin distant",
"rename": "Renommer",
"reportBugsOnGithubIssue": "Veuillez signaler les bugs sur {url}",
"restart": "Redémarrer",
"restore": "Restaurer",
"restoreSuccess": "Restauration réussie. Redémarrez l'application pour appliquer.",
"result": "Résultat",
"rotateAngel": "Angle de rotation",
"route": "Routage",
@@ -255,12 +165,6 @@
"serverDetailOrder": "Ordre des widgets de la page de détails du serveur",
"serverFuncBtns": "Boutons de fonction du serveur",
"serverOrder": "Ordre du serveur",
"serverTabConnecting": "Connexion en cours...",
"serverTabEmpty": "Aucun serveur.\nCliquez sur le fab pour en ajouter un.",
"serverTabFailed": "Échec",
"serverTabLoading": "Chargement...",
"serverTabPlzSave": "Veuillez 'enregistrer' cette clé privée à nouveau.",
"serverTabUnkown": "État inconnu",
"setting": "Paramètres",
"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`).",
@@ -307,7 +211,6 @@
"trySudo": "Essayer d'utiliser sudo",
"ttl": "TTL",
"unknown": "Inconnu",
"unknownError": "Erreur inconnue",
"unkownConvertMode": "Mode de conversion inconnu",
"update": "Mettre à jour",
"updateAll": "Tout mettre à jour",
@@ -318,13 +221,11 @@
"upload": "Télécharger",
"upsideDown": "À l'envers",
"uptime": "Temps d'activité",
"urlOrJson": "URL ou JSON",
"useCdn": "Utiliser CDN",
"useCdnTip": "Il est recommandé aux utilisateurs non chinois d'utiliser le CDN. Souhaitez-vous l'utiliser ?",
"useNoPwd": "Aucun mot de passe ne sera utilisé",
"usePodmanByDefault": "Par défaut avec Podman",
"used": "Utilisé",
"user": "Utilisateur",
"versionHaveUpdate": "Trouvé : v1.0.{build}, cliquez pour mettre à jour",
"versionUnknownUpdate": "Actuelle : v1.0.{build}, cliquez pour vérifier les mises à jour",
"versionUpdated": "Actuelle : v1.0.{build}, est à jour",
@@ -338,7 +239,6 @@
"watchNotPaired": "Aucune Apple Watch associée",
"webdavSettingEmpty": "Le paramètre Webdav est vide",
"whenOpenApp": "À l'ouverture de l'application",
"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é.",
"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.",

View File

@@ -3,81 +3,43 @@
"about": "Tentang",
"aboutThanks": "Terima kasih kepada orang -orang berikut yang berpartisipasi.",
"acceptBeta": "Terima pembaruan versi uji coba",
"add": "Menambahkan",
"addAServer": "tambahkan server",
"addPrivateKey": "Tambahkan kunci pribadi",
"addSystemPrivateKeyTip": "Saat ini tidak memiliki kunci privat, apakah Anda menambahkan kunci yang disertakan dengan sistem (~/.ssh/id_rsa)?",
"added2List": "Ditambahkan ke Daftar Tugas",
"addr": "Alamat",
"all": "Semua",
"alreadyLastDir": "Sudah di direktori terakhir.",
"askContinue": "{msg}, lanjutkan?",
"attention": "Perhatian",
"authFailTip": "Otentikasi gagal, silakan periksa apakah kata sandi/kunci/host/pengguna, dll, salah.",
"authRequired": "Auth diperlukan",
"auto": "Auto",
"autoBackupConflict": "Hanya satu pencadangan otomatis yang dapat diaktifkan pada saat yang bersamaan.",
"autoCheckUpdate": "Periksa pembaruan otomatis",
"autoConnect": "Hubungkan otomatis",
"autoRun": "Berjalan Otomatis",
"autoUpdateHomeWidget": "Widget Rumah Pembaruan Otomatis",
"backup": "Cadangan",
"backupTip": "Data yang diekspor hanya dienkripsi.\nTolong jaga keamanannya.",
"backupVersionNotMatch": "Versi cadangan tidak cocok.",
"battery": "Baterai",
"bgRun": "Jalankan di Backgroud",
"bgRunTip": "Sakelar ini hanya berarti aplikasi akan mencoba berjalan di latar belakang, apakah aplikasi dapat berjalan di latar belakang tergantung pada apakah izin diaktifkan atau tidak. Untuk Android asli, nonaktifkan \"Pengoptimalan Baterai\" di aplikasi ini, dan untuk miui, ubah kebijakan penghematan daya ke \"Tidak Terbatas\".",
"bioAuth": "Biosertifikasi",
"browser": "Peramban",
"bulkImportServers": "Impor server secara massal",
"canPullRefresh": "Anda dapat menarik untuk menyegarkan.",
"cancel": "Membatalkan",
"choose": "Memilih",
"chooseFontFile": "Pilih file font",
"choosePrivateKey": "Pilih Kunci Pribadi",
"clear": "Jernih",
"clipboard": "papan klip",
"close": "Menutup",
"cmd": "Memerintah",
"cnKeyboardComp": "Kompatibilitas dengan Android China",
"cnKeyboardCompTip": "Jika terminal munculkan keyboard aman, Anda bisa mengaktifkannya.",
"collapseUI": "Runtuh",
"collapseUITip": "Apakah akan menciutkan daftar panjang yang ada di UI secara default atau tidak",
"conn": "Koneksi",
"connected": "Terhubung",
"container": "Wadah",
"containerName": "Nama kontainer",
"containerStatus": "Status wadah",
"containerTrySudoTip": "Contohnya: Di dalam aplikasi, pengguna diatur sebagai aaa, tetapi Docker diinstal di bawah pengguna root. Dalam kasus ini, Anda perlu mengaktifkan opsi ini.",
"content": "Konten",
"convert": "Mengubah",
"copy": "Menyalin",
"copyPath": "Path Copy",
"cpuViewAsProgressTip": "Tampilkan tingkat penggunaan setiap CPU dalam gaya bilah kemajuan (gaya lama)",
"createFile": "Buat file",
"createFolder": "Membuat folder",
"cursorType": "Jenis kursor",
"customCmd": "Perintah kustom",
"customCmdDocUrl": "https://github.com/lollipopkit/flutter_server_box/wiki#custom-commands",
"customCmdHint": "\"Nama Perintah\": \"Perintah\"",
"dark": "Gelap",
"day": "Hari",
"debug": "Debug",
"decode": "Membaca sandi",
"decompress": "Dekompresi",
"delete": "Menghapus",
"deleteServers": "Penghapusan server secara batch",
"deviceName": "Nama perangkat",
"dirEmpty": "Pastikan dir kosong.",
"disabled": "Dengan disabilitas",
"disconnected": "Terputus",
"disk": "Disk",
"diskIgnorePath": "Abaikan jalan untuk disk",
"displayCpuIndex": "Tampilkan indeks CPU",
"displayName": "Nama tampilan",
"dl2Local": "Unduh {fileName} ke lokal?",
"doc": "Dokumentasi",
"dockerEditHost": "Edit Docker_host",
"dockerEmptyRunningItems": "Tidak ada wadah yang sedang berjalan.\nHal ini dapat terjadi karena:\n- Pengguna instalasi Docker tidak sama dengan nama pengguna yang dikonfigurasi di dalam Aplikasi.\n- Variabel lingkungan DOCKER_HOST tidak terbaca dengan benar. Anda bisa mendapatkannya dengan menjalankan `echo $DOCKER_HOST` di terminal.",
"dockerImagesFmt": "{count} gambar",
"dockerNotInstalled": "Docker tidak terpasang",
@@ -85,40 +47,24 @@
"dockerStatusRunningFmt": "{count} wadah berjalan.",
"doubleColumnMode": "Mode kolom ganda",
"doubleColumnTip": "Opsi ini hanya mengaktifkan fitur, apakah itu benar-benar dapat diaktifkan tergantung pada lebar perangkat",
"download": "Unduh",
"edit": "Edit",
"editVirtKeys": "Edit kunci virtual",
"editor": "Editor",
"editorHighlightTip": "Performa penyorotan kode saat ini lebih buruk, dan dapat dimatikan secara opsional untuk perbaikan.",
"encode": "Menyandi",
"envVars": "Variabel lingkungan",
"error": "Kesalahan",
"exampleName": "Nama contoh",
"experimentalFeature": "Fitur eksperimental",
"export": "Ekspor",
"extraArgs": "Args ekstra",
"failed": "Gagal",
"fallbackSshDest": "Tujuan SSH mundur",
"fdroidReleaseTip": "Jika Anda mengunduh aplikasi ini dari F-Droid, disarankan untuk mematikan opsi ini.",
"feedback": "Masukan",
"feedbackOnGithub": "Jika Anda memiliki pertanyaan, silakan umpan balik tentang GitHub.",
"fieldMustNotEmpty": "Bidang -bidang ini tidak boleh kosong.",
"fileNotExist": "{file} tidak ada",
"fileTooLarge": "File '{file}' terlalu besar {size}, max {sizeMax}",
"files": "File",
"finished": "Selesai",
"followSystem": "Ikuti sistem",
"font": "Font",
"fontSize": "Ukuran huruf",
"forExample": "Sebagai contoh",
"force": "sukarela",
"foundNUpdate": "Menemukan {count} pembaruan",
"fullScreen": "Mode Layar Penuh",
"fullScreenJitter": "Jitter layar penuh",
"fullScreenJitterHelp": "Untuk menghindari pembakaran layar",
"fullScreenTip": "Apakah mode layar penuh diaktifkan ketika perangkat diputar ke modus lanskap? Opsi ini hanya berlaku untuk tab server.",
"getPushTokenFailed": "Tidak bisa mengambil token dorong",
"gettingToken": "Mendapatkan token ...",
"goBackQ": "Datang kembali?",
"goto": "Pergi ke",
"hideTitleBar": "Sembunyikan bilah judul",
@@ -126,40 +72,26 @@
"highlight": "Sorotan kode",
"homeWidgetUrlConfig": "Konfigurasi URL Widget Rumah",
"host": "Host",
"hour": "Jam",
"httpFailedWithCode": "Permintaan gagal, kode status: {code}",
"icloudSynced": "iCloud disinkronkan dan beberapa pengaturan mungkin memerlukan pengaktifan ulang aplikasi agar dapat diterapkan.",
"ignoreCert": "Abaikan sertifikat",
"image": "Gambar",
"imagesList": "Daftar gambar",
"import": "Impor",
"inAppUpdate": "Perbarui di dalam aplikasi? Jika tidak, unduh menggunakan browser.",
"init": "Menginisialisasi",
"inner": "Batin",
"inputDomainHere": "Input domain di sini",
"install": "Install",
"installDockerWithUrl": "Silakan https://docs.docker.com/engine/install Docker pertama.",
"invalid": "Tidak valid",
"invalidJson": "JSON tidak valid",
"invalidVersion": "Versi tidak valid",
"invalidVersionHelp": "Pastikan Docker diinstal dengan benar, atau Anda menggunakan versi yang tidak dikompilasi. Jika Anda tidak memiliki masalah di atas, silakan kirimkan masalah pada {url}.",
"isBusy": "Sibuk sekarang",
"jumpServer": "Lompat server",
"keepForeground": "Simpan Aplikasi Foreground!",
"keepStatusWhenErr": "Menyimpan status server terakhir",
"keepStatusWhenErrTip": "Hanya ketika terjadi kesalahan saat menjalankan skrip",
"keyAuth": "Auth kunci",
"language": "Bahasa",
"languageName": "Indonesia",
"lastTry": "Percobaan terakhir",
"launchPage": "Halaman peluncuran",
"letterCache": "Caching huruf",
"letterCacheTip": "Direkomendasikan untuk menonaktifkan, tetapi setelah dinonaktifkan, tidak mungkin untuk memasukkan karakter CJK.",
"license": "Lisensi",
"light": "Terang",
"loadingFiles": "Memuat file ...",
"location": "Lokasi",
"log": "Catatan",
"loss": "kehilangan",
"madeWithLove": "Dibuat dengan ❤️ oleh {myGithub}",
"manual": "Manual",
@@ -167,37 +99,23 @@
"maxRetryCount": "Jumlah penyambungan kembali server",
"maxRetryCountEqual0": "Akan mencoba lagi lagi dan lagi.",
"min": "Min",
"minute": "Menit",
"mission": "Misi",
"more": "Lebih Banyak",
"moveOutServerFuncBtnsHelp": "Aktif: dapat ditampilkan di bawah setiap kartu pada halaman Tab Server. Nonaktif: dapat ditampilkan di bagian atas halaman Rincian Server.",
"ms": "MS",
"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.",
"needRestart": "Perlu memulai ulang aplikasi",
"net": "Jaringan",
"netViewType": "Jenis tampilan bersih",
"newContainer": "Wadah baru",
"noClient": "Tidak ada klien",
"noInterface": "Tidak ada antarmuka",
"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.",
"noOptions": "Tidak ada opsi",
"noPrivateKeyTip": "Kunci privat tidak ada, mungkin telah dihapus atau ada kesalahan konfigurasi.",
"noPromptAgain": "Jangan tanya lagi",
"noResult": "Tidak ada hasil",
"noSavedPrivateKey": "Tidak ada kunci pribadi yang disimpan.",
"noSavedSnippet": "Tidak ada cuplikan yang disimpan.",
"noServerAvailable": "Tidak ada server yang tersedia.",
"noTask": "Tidak bertanya",
"noUpdateAvailable": "Tidak ada pembaruan yang tersedia",
"node": "Node",
"notAvailable": "Tidak tersedia",
"notSelected": "Tidak terpilih",
"note": "Catatan",
"nullToken": "Token NULL",
"ok": "OKE",
"onServerDetailPage": "Di halaman detail server",
"onlyOneLine": "Hanya tampilkan sebagai satu baris (dapat digulir)",
"onlyWhenCoreBiggerThan8": "Berlaku hanya ketika jumlah inti > 8",
@@ -209,7 +127,6 @@
"path": "Jalur",
"percentOfSize": "{percent}% dari {size}",
"permission": "Izin",
"pickFile": "Pilih file",
"pingAvg": "Rata -rata:",
"pingInputIP": "Harap masukkan IP / domain target.",
"pingNoServer": "Tidak ada server untuk melakukan ping.\nHarap tambahkan server di tab Server.",
@@ -217,8 +134,6 @@
"pkgUpgradeTip": "Harap cadangkan sistem Anda sebelum memperbarui.",
"platformNotSupportUpdate": "Platform saat ini tidak mendukung pembaruan aplikasi.\nSilakan bangun dari sumber dan instal.",
"plugInType": "Jenis Penyisipan",
"plzEnterHost": "Harap masukkan host.",
"plzSelectKey": "Pilih kunci.",
"port": "Port",
"preview": "Pratinjau",
"primaryColorSeed": "Warna utama",
@@ -231,16 +146,11 @@
"pwd": "Kata sandi",
"read": "Baca",
"reboot": "Reboot",
"rememberChoice": "Ingat pilihan",
"rememberPwdInMem": "Ingat kata sandi di dalam memori",
"rememberPwdInMemTip": "Digunakan untuk kontainer, menangguhkan, dll.",
"rememberWindowSize": "Ingat ukuran jendela",
"remotePath": "Jalur jarak jauh",
"rename": "Ganti nama",
"reportBugsOnGithubIssue": "Harap laporkan bug di {url}",
"restart": "Mengulang kembali",
"restore": "Memulihkan",
"restoreSuccess": "Kembalikan kesuksesan. Mulai ulang aplikasi untuk diterapkan.",
"result": "Hasil",
"rotateAngel": "Sudut rotasi",
"route": "Routing",
@@ -255,12 +165,6 @@
"serverDetailOrder": "Detail pesanan widget halaman",
"serverFuncBtns": "Tombol fungsi server",
"serverOrder": "Pesanan server",
"serverTabConnecting": "Menghubungkan ...",
"serverTabEmpty": "Tidak ada server.\nKlik fab untuk menambahkan satu.",
"serverTabFailed": "Gagal",
"serverTabLoading": "Memuat...",
"serverTabPlzSave": "Harap 'simpan' kunci pribadi ini lagi.",
"serverTabUnkown": "Negara yang tidak diketahui",
"setting": "Pengaturan",
"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`).",
@@ -307,7 +211,6 @@
"trySudo": "Cobalah menggunakan sudo",
"ttl": "TTL",
"unknown": "Tidak dikenal",
"unknownError": "Kesalahan yang tidak diketahui",
"unkownConvertMode": "Mode Konversi Tidak Diketahui",
"update": "Memperbarui",
"updateAll": "Perbarui semua",
@@ -318,13 +221,11 @@
"upload": "Mengunggah",
"upsideDown": "Terbalik",
"uptime": "Uptime",
"urlOrJson": "URL atau JSON",
"useCdn": "Menggunakan CDN",
"useCdnTip": "Pengguna non-Cina disarankan menggunakan CDN. Apakah Anda ingin menggunakannya?",
"useNoPwd": "Tidak ada kata sandi yang akan digunakan",
"usePodmanByDefault": "Menggunakan Podman sebagai bawaan",
"used": "Digunakan",
"user": "Username",
"versionHaveUpdate": "Ditemukan: v1.0.{build}, klik untuk memperbarui",
"versionUnknownUpdate": "Saat ini: v1.0.{build}. Klik untuk memeriksa pembaruan.",
"versionUpdated": "Saat ini: v1.0.{build}, mutakhir",
@@ -338,7 +239,6 @@
"watchNotPaired": "Tidak ada Apple Watch yang dipasangkan",
"webdavSettingEmpty": "Pengaturan webdav kosong",
"whenOpenApp": "Saat membuka aplikasi",
"willTakEeffectImmediately": "Akan segera berlaku",
"wolTip": "Setelah mengonfigurasi WOL (Wake-on-LAN), permintaan WOL dikirim setiap kali server terhubung.",
"write": "Tulis",
"writeScriptFailTip": "Penulisan ke skrip gagal, mungkin karena tidak ada izin atau direktori tidak ada.",

View File

@@ -3,81 +3,43 @@
"about": "約",
"aboutThanks": "以下の参加者に感謝します。",
"acceptBeta": "テストバージョンの更新を受け入れる",
"add": "追加",
"addAServer": "サーバーを追加する",
"addPrivateKey": "秘密鍵を追加",
"addSystemPrivateKeyTip": "現在秘密鍵がありません。システムのデフォルト(~/.ssh/id_rsa)を追加しますか?",
"added2List": "タスクリストに追加されました",
"addr": "アドレス",
"all": "すべて",
"alreadyLastDir": "すでに最上位のディレクトリです",
"askContinue": "{msg}、続行しますか?",
"attention": "注意",
"authFailTip": "認証に失敗しました。パスワード/鍵/ホスト/ユーザーなどが間違っていないか確認してください。",
"authRequired": "認証が必要",
"auto": "自動",
"autoBackupConflict": "自動バックアップは一度に一つしか開始できません",
"autoCheckUpdate": "自動的に更新をチェック",
"autoConnect": "自動接続",
"autoRun": "自動実行",
"autoUpdateHomeWidget": "ホームウィジェットを自動更新",
"backup": "バックアップ",
"backupTip": "エクスポートされたデータは簡単に暗号化されています。適切に保管してください。",
"backupVersionNotMatch": "バックアップバージョンが一致しないため、復元できません",
"battery": "バッテリー",
"bgRun": "バックグラウンド実行",
"bgRunTip": "このスイッチはプログラムがバックグラウンドで実行を試みることを意味しますが、実際にバックグラウンドで実行できるかどうかは、権限が有効になっているかに依存します。AOSPベースのAndroid ROMでは、このアプリの「バッテリー最適化」をオフにしてください。MIUIでは、省エネモードを「無制限」に変更してください。",
"bioAuth": "生体認証",
"browser": "ブラウザ",
"bulkImportServers": "サーバーを一括インポートする",
"canPullRefresh": "引っ張って更新できます",
"cancel": "キャンセル",
"choose": "選択",
"chooseFontFile": "フォントファイルを選択",
"choosePrivateKey": "秘密鍵を選択",
"clear": "クリア",
"clipboard": "クリップボード",
"close": "閉じる",
"cmd": "コマンド",
"cnKeyboardComp": "中国のAndroidとの互換性",
"cnKeyboardCompTip": "ターミナルがセキュアキーボードを表示した場合、それを有効にできます。",
"collapseUI": "UIを折りたたむ",
"collapseUITip": "UIの長いリストをデフォルトで折りたたむかどうか",
"conn": "接続",
"connected": "接続済み",
"container": "コンテナ",
"containerName": "コンテナ名",
"containerStatus": "コンテナの状態",
"containerTrySudoTip": "例アプリ内でユーザーをaaaに設定しているが、Dockerがrootユーザーでインストールされている場合、このオプションを有効にする必要があります",
"content": "コンテンツ",
"convert": "変換",
"copy": "コピー",
"copyPath": "パスをコピー",
"cpuViewAsProgressTip": "各CPUの使用率をプログレスバースタイルで表示する旧スタイル",
"createFile": "ファイルを作成",
"createFolder": "フォルダーを作成",
"cursorType": "カーソルタイプ",
"customCmd": "カスタムコマンド",
"customCmdDocUrl": "https://github.com/lollipopkit/flutter_server_box/wiki#custom-commands",
"customCmdHint": "\"コマンド名\": \"コマンド\"",
"dark": "ダーク",
"day": "日",
"debug": "デバッグ",
"decode": "デコード",
"decompress": "解凍",
"delete": "削除",
"deleteServers": "サーバーを一括削除",
"deviceName": "デバイス名",
"dirEmpty": "フォルダーが空であることを確認してください",
"disabled": "無効",
"disconnected": "接続が切断されました",
"disk": "ディスク",
"diskIgnorePath": "無視されたディスクパス",
"displayCpuIndex": "CPUインデックスを表示する",
"displayName": "表示名",
"dl2Local": "{fileName}をローカルにダウンロードしますか?",
"doc": "ドキュメント",
"dockerEditHost": "DOCKER_HOSTを編集",
"dockerEmptyRunningItems": "実行中のコンテナがありません。\nこれは次の理由による可能性があります\n- Dockerのインストールユーザーとアプリ内の設定されたユーザー名が異なる\n- 環境変数DOCKER_HOSTが正しく読み込まれていない。ターミナルで`echo $DOCKER_HOST`を実行して取得できます。",
"dockerImagesFmt": "合計{count}イメージ",
"dockerNotInstalled": "Dockerがインストールされていません",
@@ -85,40 +47,24 @@
"dockerStatusRunningFmt": "{count}個のコンテナが実行中",
"doubleColumnMode": "ダブルカラムモード",
"doubleColumnTip": "このオプションは機能を有効にするだけで、実際に有効にできるかどうかはデバイスの幅に依存します",
"download": "ダウンロード",
"edit": "編集",
"editVirtKeys": "仮想キーを編集",
"editor": "エディター",
"editorHighlightTip": "現在のコードハイライトのパフォーマンスはかなり悪いため、改善するために無効にすることを選択できます。",
"encode": "エンコード",
"envVars": "環境変数",
"error": "エラー",
"exampleName": "名前例",
"experimentalFeature": "実験的な機能",
"export": "エクスポート",
"extraArgs": "追加引数",
"failed": "失敗しました",
"fallbackSshDest": "フォールバックSSH宛先",
"fdroidReleaseTip": "このアプリをF-Droidからダウンロードした場合、このオプションをオフにすることをお勧めします。",
"feedback": "フィードバック",
"feedbackOnGithub": "問題がある場合は、GitHubでフィードバックしてください",
"fieldMustNotEmpty": "これらの入力フィールドは空にできません。",
"fileNotExist": "{file}は存在しません",
"fileTooLarge": "ファイル '{file}' は大きすぎます '{size}'、{sizeMax} を超えています",
"files": "ファイル",
"finished": "完了しました",
"followSystem": "システムに従う",
"font": "フォント",
"fontSize": "フォントサイズ",
"forExample": "例えば",
"force": "強制",
"foundNUpdate": "{count}個の更新が見つかりました",
"fullScreen": "フルスクリーンモード",
"fullScreenJitter": "フルスクリーンモードのジッター",
"fullScreenJitterHelp": "焼き付き防止",
"fullScreenTip": "デバイスが横向きに回転したときにフルスクリーンモードを有効にしますか?このオプションはサーバータブにのみ適用されます。",
"getPushTokenFailed": "プッシュトークンを取得できませんでした",
"gettingToken": "トークンを取得しています...",
"goBackQ": "戻りますか?",
"goto": "移動",
"hideTitleBar": "タイトルバーを非表示にする",
@@ -126,40 +72,26 @@
"highlight": "コードハイライト",
"homeWidgetUrlConfig": "ホームウィジェットURL設定",
"host": "ホスト",
"hour": "時間",
"httpFailedWithCode": "リクエスト失敗、ステータスコード: {code}",
"icloudSynced": "iCloudが同期されました。一部の設定はアプリを再起動する必要があります。",
"ignoreCert": "証明書を無視する",
"image": "イメージ",
"imagesList": "イメージリスト",
"import": "インポート",
"inAppUpdate": "アプリ内で更新しますか?それ以外の場合は、ブラウザを使用してダウンロードしてください。",
"init": "初期化する",
"inner": "内蔵",
"inputDomainHere": "ここにドメインを入力",
"install": "インストール",
"installDockerWithUrl": "最初に https://docs.docker.com/engine/install dockerをインストールしてください",
"invalid": "無効",
"invalidJson": "無効なJSON",
"invalidVersion": "サポートされていないバージョン",
"invalidVersionHelp": "dockerが正しくインストールされていること、または自己コンパイルされたバージョンを使用していないことを確認してください。問題がない場合は、{url}で問題を報告してください。",
"isBusy": "現在忙しいです",
"jumpServer": "ジャンプサーバー",
"keepForeground": "アプリを前面に保ってください!",
"keepStatusWhenErr": "エラー時に前回のサーバーステータスを保持",
"keepStatusWhenErrTip": "スクリプトの実行エラーに限ります",
"keyAuth": "キー認証",
"language": "言語",
"languageName": "日本語",
"lastTry": "最後の試み",
"launchPage": "起動ページ",
"letterCache": "文字キャッシング",
"letterCacheTip": "無効にすることを推奨しますが、無効にした後はCJK文字を入力することができなくなります。",
"license": "オープンソースライセンス",
"light": "ライト",
"loadingFiles": "ディレクトリを読み込んでいます...",
"location": "場所",
"log": "ログ",
"loss": "パケットロス",
"madeWithLove": "❤️で作成された {myGithub}",
"manual": "マニュアル",
@@ -167,37 +99,23 @@
"maxRetryCount": "サーバーの再接続試行回数",
"maxRetryCountEqual0": "無限に再試行します",
"min": "最小",
"minute": "分",
"mission": "ミッション",
"more": "もっと",
"moveOutServerFuncBtnsHelp": "有効にする:サーバータブの各カードの下に表示されます。無効にする:サーバーの詳細ページの上部に表示されます。",
"ms": "ミリ秒",
"name": "名前",
"needHomeDir": "Synologyユーザーの場合は、[こちらをご覧ください](https://kb.synology.com/DSM/tutorial/user_enable_home_service)。他のシステムのユーザーは、ホームディレクトリの作成方法を検索する必要があります。",
"needRestart": "アプリを再起動する必要があります",
"net": "ネットワーク",
"netViewType": "ネットワークビュータイプ",
"newContainer": "新しいコンテナを作成",
"noClient": "SSH接続がありません",
"noInterface": "使用可能なインターフェースがありません",
"noLineChart": "折れ線グラフを使用しない",
"noLineChartForCpu": "CPUに折れ線グラフを使わない",
"noNotiPerm": "通知の権限がないため、アプリの更新のダウンロード中に進行状況が表示されない場合があります。",
"noOptions": "選択肢がありません",
"noPrivateKeyTip": "秘密鍵が存在しません。削除されたか、設定ミスがある可能性があります。",
"noPromptAgain": "再度確認しない",
"noResult": "結果なし",
"noSavedPrivateKey": "保存された秘密鍵がありません。",
"noSavedSnippet": "保存されたスニペットがありません。",
"noServerAvailable": "使用可能なサーバーがありません。",
"noTask": "タスクがありません",
"noUpdateAvailable": "利用可能な更新はありません",
"node": "ノード",
"notAvailable": "利用不可",
"notSelected": "選択されていません",
"note": "メモ",
"nullToken": "トークンなし",
"ok": "OK",
"onServerDetailPage": "サーバーの詳細ページで",
"onlyOneLine": "一行のみ表示(スクロール可能)",
"onlyWhenCoreBiggerThan8": "コア数が8より大きい場合にのみ有効",
@@ -209,7 +127,6 @@
"path": "パス",
"percentOfSize": "{size} の {percent}%",
"permission": "権限",
"pickFile": "ファイルを選択",
"pingAvg": "平均:",
"pingInputIP": "対象のIPまたはドメインを入力してください",
"pingNoServer": "Pingに使用するサーバーがありません\nサーバータブでサーバーを追加してから再試行してください",
@@ -217,8 +134,6 @@
"pkgUpgradeTip": "アップデートする前にシステムのバックアップを取ってください。",
"platformNotSupportUpdate": "現在のプラットフォームは更新をサポートしていません。最新のソースコードをコンパイルして手動でインストールしてください",
"plugInType": "挿入タイプ",
"plzEnterHost": "ホストを入力してください",
"plzSelectKey": "秘密鍵を選択してください",
"port": "ポート",
"preview": "プレビュー",
"primaryColorSeed": "プライマリーカラーシード",
@@ -231,16 +146,11 @@
"pwd": "パスワード",
"read": "読み取り",
"reboot": "再起動",
"rememberChoice": "選択を記憶する",
"rememberPwdInMem": "メモリにパスワードを記憶する",
"rememberPwdInMemTip": "コンテナ、一時停止などに使用されます。",
"rememberWindowSize": "ウィンドウサイズを記憶する",
"remotePath": "リモートパス",
"rename": "名前を変更",
"reportBugsOnGithubIssue": "{url}で問題を報告してください",
"restart": "再開",
"restore": "復元",
"restoreSuccess": "復元に成功しました。変更を適用するためにアプリを再起動する必要があります",
"result": "結果",
"rotateAngel": "回転角度",
"route": "ルーティング",
@@ -255,12 +165,6 @@
"serverDetailOrder": "詳細ページのウィジェット順序",
"serverFuncBtns": "サーバー機能ボタン",
"serverOrder": "サーバー順序",
"serverTabConnecting": "接続中...",
"serverTabEmpty": "現在サーバーはありません。\n右下のボタンをクリックして追加してください。",
"serverTabFailed": "失敗",
"serverTabLoading": "読み込み中...",
"serverTabPlzSave": "この秘密鍵を再保存してください",
"serverTabUnkown": "不明な状態",
"setting": "設定",
"sftpDlPrepare": "サーバーへの接続を準備中...",
"sftpEditorTip": "空の場合は、アプリ内蔵のファイルエディタを使用します。値がある場合は、リモートサーバーのエディタ(例:`vim`)を使用します(`EDITOR` に従って自動検出することをお勧めします)。",
@@ -307,7 +211,6 @@
"trySudo": "sudoを試みる",
"ttl": "TTL",
"unknown": "不明",
"unknownError": "未知のエラー",
"unkownConvertMode": "未知の変換モード",
"update": "更新",
"updateAll": "すべて更新",
@@ -318,13 +221,11 @@
"upload": "アップロード",
"upsideDown": "上下逆転",
"uptime": "稼働時間",
"urlOrJson": "URLまたはJSON",
"useCdn": "CDNの使用",
"useCdnTip": "中国以外のユーザーにはCDNの使用が推奨されています。ご利用しますか",
"useNoPwd": "パスワードなしで使用します",
"usePodmanByDefault": "デフォルトでPodmanを使用",
"used": "使用済み",
"user": "ユーザー",
"versionHaveUpdate": "新しいバージョンが見つかりましたv1.0.{build}、クリックして更新",
"versionUnknownUpdate": "現在v1.0.{build}、更新をチェックするためにクリック",
"versionUpdated": "現在v1.0.{build}、最新バージョンです",
@@ -338,7 +239,6 @@
"watchNotPaired": "ペアリングされたApple Watchがありません",
"webdavSettingEmpty": "Webdavの設定が空です",
"whenOpenApp": "アプリを開くとき",
"willTakEeffectImmediately": "変更は即座に有効になります",
"wolTip": "WOLWake-on-LANを設定した後、サーバーに接続するたびにWOLリクエストが送信されます。",
"write": "書き込み",
"writeScriptFailTip": "スクリプトの書き込みに失敗しました。権限がないかディレクトリが存在しない可能性があります。",

View File

@@ -3,81 +3,43 @@
"about": "Over",
"aboutThanks": "Met dank aan de volgende mensen die hebben deelgenomen aan.",
"acceptBeta": "Accepteer testversie-updates",
"add": "Toevoegen",
"addAServer": "een server toevoegen",
"addPrivateKey": "Privésleutel toevoegen",
"addSystemPrivateKeyTip": "Er is momenteel geen privésleutel, wilt u degene toevoegen die bij het systeem wordt geleverd (~/.ssh/id_rsa)?",
"added2List": "Toegevoegd aan takenlijst",
"addr": "Adres",
"all": "Alle",
"alreadyLastDir": "Al in de laatst gebruikte map.",
"askContinue": "{msg}. Doorgaan?",
"attention": "Let op",
"authFailTip": "Authenticatie mislukt, controleer of het wachtwoord/sleutel/host/gebruiker, enz., incorrect zijn.",
"authRequired": "Authenticatie vereist",
"auto": "Auto",
"autoBackupConflict": "Er kan slechts één automatische back-up tegelijk worden ingeschakeld.",
"autoCheckUpdate": "Automatisch controleren op update",
"autoConnect": "Automatisch verbinden",
"autoRun": "Automatisch uitvoeren",
"autoUpdateHomeWidget": "Automatische update van home-widget",
"backup": "Back-up",
"backupTip": "De geëxporteerde gegevens zijn simpelweg versleuteld. \nBewaar deze aub veilig.",
"backupVersionNotMatch": "Back-upversie komt niet overeen.",
"battery": "Batterij",
"bgRun": "Uitvoeren op de achtergrond",
"bgRunTip": "Deze schakelaar betekent alleen dat het programma zal proberen op de achtergrond uit te voeren, of het in de achtergrond kan worden uitgevoerd, hangt af van of de toestemming is ingeschakeld of niet. Voor native Android, schakel \"Batterijoptimalisatie\" uit in deze app, en voor miui, wijzig de energiebesparingsbeleid naar \"Onbeperkt\".",
"bioAuth": "Biometrische authenticatie",
"browser": "Browser",
"bulkImportServers": "Servers batchgewijs importeren",
"canPullRefresh": "Je kunt verversen door te slepen.",
"cancel": "Annuleren",
"choose": "Kiezen",
"chooseFontFile": "Kies een font bestand",
"choosePrivateKey": "Privésleutel kiezen",
"clear": "Wissen",
"clipboard": "Klembord",
"close": "Sluiten",
"cmd": "Opdracht",
"cnKeyboardComp": "Compatibiliteit met Chinese Android",
"cnKeyboardCompTip": "Als de terminal een beveiligd toetsenbord weergeeft, kunt u dit inschakelen.",
"collapseUI": "Inklappen",
"collapseUITip": "Of lange lijsten in de UI standaard moeten worden ingeklapt",
"conn": "Verbinding",
"connected": "Verbonden",
"container": "Container",
"containerName": "Container naam",
"containerStatus": "Containerstatus",
"containerTrySudoTip": "Bijvoorbeeld: in de app is de gebruiker ingesteld op aaa, maar Docker is geïnstalleerd onder de rootgebruiker. In dit geval moet u deze optie inschakelen.",
"content": "Inhoud",
"convert": "Converteren",
"copy": "Kopiëren",
"copyPath": "Pad kopiëren",
"cpuViewAsProgressTip": "Toon het gebruik van elke CPU in een voortgangsbalkstijl (oude stijl)",
"createFile": "Bestand aanmaken",
"createFolder": "Map aanmaken",
"cursorType": "Cursortype",
"customCmd": "Aangepaste opdrachten",
"customCmdDocUrl": "https://github.com/lollipopkit/flutter_server_box/wiki#custom-commands",
"customCmdHint": "\"Opdrachtnaam\": \"Opdracht\"",
"dark": "Donker",
"day": "Dag",
"debug": "Debuggen",
"decode": "Decoderen",
"decompress": "Decomprimeren",
"delete": "Verwijderen",
"deleteServers": "Servers batchgewijs verwijderen",
"deviceName": "Apparaatnaam",
"dirEmpty": "Zorg ervoor dat de map leeg is.",
"disabled": "Uitgeschakeld",
"disconnected": "Verbroken",
"disk": "Schijf",
"diskIgnorePath": "Pad negeren voor schijf",
"displayCpuIndex": "Toon de CPU-index",
"displayName": "Weergavenaam",
"dl2Local": "Download {fileName} naar lokaal?",
"doc": "Documentatie",
"dockerEditHost": "DOCKER_HOST bewerken",
"dockerEmptyRunningItems": "Er zijn geen actieve containers.\nDit kan komen doordat:\n- De Docker-installatiegebruiker niet overeenkomt met de gebruikersnaam die is geconfigureerd binnen de app.\n- De omgevingsvariabele DOCKER_HOST is niet correct gelezen. U kunt deze krijgen door `echo $DOCKER_HOST` in de terminal uit te voeren.",
"dockerImagesFmt": "{count} afbeeldingen",
"dockerNotInstalled": "Docker niet geïnstalleerd",
@@ -85,40 +47,24 @@
"dockerStatusRunningFmt": "{count} container actief.",
"doubleColumnMode": "Dubbele kolommodus",
"doubleColumnTip": "Deze optie schakelt alleen de functie in, of deze daadwerkelijk kan worden ingeschakeld, hangt af van de breedte van het apparaat",
"download": "Downloaden",
"edit": "Bewerken",
"editVirtKeys": "Virtuele toetsen bewerken",
"editor": "Editor",
"editorHighlightTip": "De huidige codehighlighting-prestaties zijn slechter en kunnen optioneel worden uitgeschakeld om te verbeteren.",
"encode": "Coderen",
"envVars": "Omgevingsvariabele",
"error": "Fout",
"exampleName": "Voorbeeldnaam",
"experimentalFeature": "Experimentele functie",
"export": "Exporteren",
"extraArgs": "Extra argumenten",
"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",
"feedbackOnGithub": "Als je vragen hebt, geef dan feedback op Github.",
"fieldMustNotEmpty": "Deze velden mogen niet leeg zijn.",
"fileNotExist": "{file} bestaat niet",
"fileTooLarge": "Bestand '{file}' te groot {size}, max {sizeMax}",
"files": "Bestanden",
"finished": "Voltooid",
"followSystem": "Volg systeem",
"font": "Lettertype",
"fontSize": "Lettergrootte",
"forExample": "Bijvoorbeeld",
"force": "Forceer",
"foundNUpdate": "{count} update gevonden",
"fullScreen": "Volledig schermmodus",
"fullScreenJitter": "Volledig scherm trilling",
"fullScreenJitterHelp": "Om inbranden van het scherm te voorkomen",
"fullScreenTip": "Moet de volledig schermmodus worden ingeschakeld wanneer het apparaat naar de liggende modus wordt gedraaid? Deze optie is alleen van toepassing op het servertabblad.",
"getPushTokenFailed": "Kan push-token niet ophalen",
"gettingToken": "Token ophalen...",
"goBackQ": "Terug gaan?",
"goto": "Ga naar",
"hideTitleBar": "Titelbalk verbergen",
@@ -126,40 +72,26 @@
"highlight": "Code-highlight",
"homeWidgetUrlConfig": "Home-widget-url configureren",
"host": "Host",
"hour": "Uur",
"httpFailedWithCode": "verzoek mislukt, statuscode: {code}",
"icloudSynced": "iCloud wordt gesynchroniseerd en sommige instellingen vereisen mogelijk een herstart van de app om van kracht te worden.",
"ignoreCert": "Certificaat negeren",
"image": "Afbeelding",
"imagesList": "Lijst met afbeeldingen",
"import": "Importeren",
"inAppUpdate": "Bijwerken binnen de app? Anders downloaden via een browser.",
"init": "Initialiseren",
"inner": "Intern",
"inputDomainHere": "Voer hier domein in",
"install": "Installeren",
"installDockerWithUrl": "Installeer eerst docker via https://docs.docker.com/engine/install.",
"invalid": "Ongeldig",
"invalidJson": "Ongeldige JSON",
"invalidVersion": "Ongeldige versie",
"invalidVersionHelp": "Zorg ervoor dat docker correct is geïnstalleerd, of dat u een niet-zelf-gecompileerde versie gebruikt. Als dat niet het geval is, meld dan een probleem op {url}.",
"isBusy": "Is momenteel bezig",
"jumpServer": "Spring naar server",
"keepForeground": "Houd de app op de voorgrond!",
"keepStatusWhenErr": "Behoud de laatste serverstatus",
"keepStatusWhenErrTip": "Alleen in geval van een fout tijdens de scriptuitvoering",
"keyAuth": "Sleutelauthenticatie",
"language": "Taal",
"languageName": "Nederlands",
"lastTry": "Laatste poging",
"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",
"light": "Licht",
"loadingFiles": "Bestanden laden...",
"location": "Locatie",
"log": "Logboek",
"loss": "verlies",
"madeWithLove": "Gemaakt met ❤️ door {myGithub}",
"manual": "Handleiding",
@@ -167,37 +99,23 @@
"maxRetryCount": "Aantal serverherverbindingen",
"maxRetryCountEqual0": "Zal opnieuw blijven proberen.",
"min": "min",
"minute": "Minuut",
"mission": "Missie",
"more": "Meer",
"moveOutServerFuncBtnsHelp": "Aan: kan worden weergegeven onder elke kaart op de Server-tabbladpagina. Uit: kan worden weergegeven bovenaan de Serverdetails-pagina.",
"ms": "ms",
"name": "Naam",
"needHomeDir": "Als u een Synology-gebruiker bent, [zie hier](https://kb.synology.com/DSM/tutorial/user_enable_home_service). Gebruikers van andere systemen moeten zoeken hoe ze een home directory kunnen creëren.",
"needRestart": "App moet opnieuw worden gestart",
"net": "Netwerk",
"netViewType": "Netweergavetype",
"newContainer": "Nieuwe container",
"noClient": "Geen client",
"noInterface": "Geen interface",
"noLineChart": "lijndiagrammen gebruiken",
"noLineChartForCpu": "Gebruik geen lijndiagrammen voor CPU",
"noNotiPerm": "Geen meldingsmachtigingen, mogelijk geen voortgangsindicatie bij het downloaden van app-updates.",
"noOptions": "Geen opties",
"noPrivateKeyTip": "De privésleutel bestaat niet, deze is mogelijk verwijderd of er is een configuratiefout.",
"noPromptAgain": "Niet meer vragen",
"noResult": "Geen resultaat",
"noSavedPrivateKey": "Geen opgeslagen privésleutels.",
"noSavedSnippet": "Geen opgeslagen fragmenten.",
"noServerAvailable": "Geen server beschikbaar.",
"noTask": "Geen taak",
"noUpdateAvailable": "Geen update beschikbaar",
"node": "Node",
"notAvailable": "Niet beschikbaar",
"notSelected": "Niet geselecteerd",
"note": "Opmerking",
"nullToken": "Null-token",
"ok": "OK",
"onServerDetailPage": "Op serverdetailspagina",
"onlyOneLine": "Alleen als één regel weergeven (scrollbaar)",
"onlyWhenCoreBiggerThan8": "Alleen effectief wanneer het aantal cores > 8",
@@ -209,7 +127,6 @@
"path": "Pad",
"percentOfSize": "{percent}% van {size}",
"permission": "Machtigingen",
"pickFile": "Bestand kiezen",
"pingAvg": "Gem:",
"pingInputIP": "Voer een doel-IP / domein in.",
"pingNoServer": "Geen server om te pingen.\nVoeg een server toe in het servertabblad.",
@@ -217,8 +134,6 @@
"pkgUpgradeTip": "Maak een back-up van uw systeem voordat u een update uitvoert.",
"platformNotSupportUpdate": "Huidig platform ondersteunt geen updates in de app.\nBouw het alstublieft uit bron en installeer het.",
"plugInType": "Invoegingstype",
"plzEnterHost": "Voer host in a.u.b.",
"plzSelectKey": "Selecteer a.u.b. een sleutel.",
"port": "Poort",
"preview": "Voorbeeld",
"primaryColorSeed": "Basis kleurzaad",
@@ -231,16 +146,11 @@
"pwd": "Wachtwoord",
"read": "Lezen",
"reboot": "Herstart",
"rememberChoice": "Selectie onthouden",
"rememberPwdInMem": "Wachtwoord onthouden in geheugen",
"rememberPwdInMemTip": "Gebruikt voor containers, opschorting, enz.",
"rememberWindowSize": "Venstergrootte onthouden",
"remotePath": "Extern pad",
"rename": "Hernoemen",
"reportBugsOnGithubIssue": "Meld alstublieft bugs op {url}",
"restart": "Herstarten",
"restore": "Herstellen",
"restoreSuccess": "Herstellen geslaagd. App herstarten om toe te passen.",
"result": "Resultaat",
"rotateAngel": "Rotatiehoek",
"route": "Route",
@@ -255,12 +165,6 @@
"serverDetailOrder": "Volgorde van widget op detailpagina",
"serverFuncBtns": "Server functieknoppen",
"serverOrder": "Servervolgorde",
"serverTabConnecting": "Verbinding maken...",
"serverTabEmpty": "Er is geen server.\nKlik op fab om er een toe te voegen.",
"serverTabFailed": "Mislukt",
"serverTabLoading": "Laden...",
"serverTabPlzSave": "Sla deze privésleutel opnieuw op.",
"serverTabUnkown": "Onbekende status",
"setting": "Instellingen",
"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`).",
@@ -307,7 +211,6 @@
"trySudo": "Probeer sudo te gebruiken",
"ttl": "TTL",
"unknown": "Onbekend",
"unknownError": "Onbekende fout",
"unkownConvertMode": "Onbekende conversiemodus",
"update": "Bijwerken",
"updateAll": "Alles bijwerken",
@@ -318,13 +221,11 @@
"upload": "Upload",
"upsideDown": "Ondersteboven",
"uptime": "Uptime",
"urlOrJson": "URL of JSON",
"useCdn": "Gebruikt CDN",
"useCdnTip": "Niet-chinese gebruikers worden aangeraden om deze CDN te gebruiken. Wil je dat?",
"useNoPwd": "Er zal geen wachtwoord gebruikt worden",
"usePodmanByDefault": "Valt terug op Podman",
"used": "Gebruikt",
"user": "Gebruiker",
"versionHaveUpdate": "Gevonden: v1.0.{build}, klik om bij te werken",
"versionUnknownUpdate": "Huidig: v1.0.{build}, klik om te kijken naar een nieuwere versie",
"versionUpdated": "Huidig: v1.0.{build}, is bijgewerkt naar de laatste versie",
@@ -338,7 +239,6 @@
"watchNotPaired": "Geen gekoppelde Apple Watch",
"webdavSettingEmpty": "Webdav-instelling is leeg",
"whenOpenApp": "Bij het openen van de app",
"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.",
"write": "Schrijven",
"writeScriptFailTip": "Het schrijven naar het script is mislukt, mogelijk door gebrek aan rechten of omdat de map niet bestaat.",

View File

@@ -3,81 +3,43 @@
"about": "Sobre",
"aboutThanks": "Agradecimentos a todos os participantes.",
"acceptBeta": "Aceitar atualizações da versão de teste",
"add": "Adicionar",
"addAServer": "Adicionar um servidor",
"addPrivateKey": "Adicionar uma chave privada",
"addSystemPrivateKeyTip": "Atualmente, não há nenhuma chave privada. Gostaria de adicionar a chave do sistema (~/.ssh/id_rsa)?",
"added2List": "Adicionado à lista de tarefas",
"addr": "Endereço",
"all": "Todos",
"alreadyLastDir": "Já é o diretório mais alto",
"askContinue": "{msg}, continuar?",
"attention": "Atenção",
"authFailTip": "Autenticação falhou, por favor verifique se a senha/chave/host/usuário, etc., estão incorretos.",
"authRequired": "Autenticação necessária",
"auto": "Automático",
"autoBackupConflict": "Apenas um backup automático pode ser ativado por vez",
"autoCheckUpdate": "Verificação automática de atualização",
"autoConnect": "Conexão automática",
"autoRun": "Execução automática",
"autoUpdateHomeWidget": "Atualização automática do widget da tela inicial",
"backup": "Backup",
"backupTip": "Os dados exportados são criptografados de forma simples, por favor, guarde-os com segurança.",
"backupVersionNotMatch": "Versão de backup não compatível, não é possível restaurar",
"battery": "Bateria",
"bgRun": "Execução em segundo plano",
"bgRunTip": "Este interruptor indica que o programa tentará rodar em segundo plano, mas a capacidade de fazer isso depende das permissões concedidas. No Android nativo, desative a 'Otimização de bateria' para este app, no MIUI, altere a estratégia de economia de energia para 'Sem restrições'.",
"bioAuth": "Autenticação biométrica",
"browser": "Navegador",
"bulkImportServers": "Importar servidores em lote",
"canPullRefresh": "Pode puxar para atualizar",
"cancel": "Cancelar",
"choose": "Escolher",
"chooseFontFile": "Escolher arquivo de fonte",
"choosePrivateKey": "Escolher chave privada",
"clear": "Limpar",
"clipboard": "Área de transferência",
"close": "Fechar",
"cmd": "Comando",
"cnKeyboardComp": "Compatibilidade com Android chinês",
"cnKeyboardCompTip": "Se o terminal abrir um teclado seguro, você pode ativá-lo.",
"collapseUI": "Colapsar",
"collapseUITip": "Deve colapsar listas longas na UI por padrão?",
"conn": "Conectar",
"connected": "Conectado",
"container": "Contêiner",
"containerName": "Nome do contêiner",
"containerStatus": "Estado do contêiner",
"containerTrySudoTip": "Por exemplo: se o usuário for definido como aaa dentro do app, mas o Docker estiver instalado sob o usuário root, esta opção precisará ser ativada",
"content": "Conteúdo",
"convert": "Converter",
"copy": "Copiar",
"copyPath": "Copiar caminho",
"cpuViewAsProgressTip": "Exiba a taxa de uso de cada CPU em estilo de barra de progresso (estilo antigo)",
"createFile": "Criar arquivo",
"createFolder": "Criar pasta",
"cursorType": "Tipo de cursor",
"customCmd": "Comandos personalizados",
"customCmdDocUrl": "https://github.com/lollipopkit/flutter_server_box/wiki#custom-commands",
"customCmdHint": "\"Nome do comando\": \"Comando\"",
"dark": "Escuro",
"day": "Dia",
"debug": "Debugar",
"decode": "Decodificar",
"decompress": "Descomprimir",
"delete": "Excluir",
"deleteServers": "Excluir servidores em lote",
"deviceName": "Nome do dispositivo",
"dirEmpty": "Certifique-se de que a pasta está vazia",
"disabled": "Desativado",
"disconnected": "Desconectado",
"disk": "Disco",
"diskIgnorePath": "Caminhos de disco ignorados",
"displayCpuIndex": "Exiba o índice de CPU",
"displayName": "Nome de exibição",
"dl2Local": "Baixar {fileName} para o local?",
"doc": "Documentação",
"dockerEditHost": "Editar DOCKER_HOST",
"dockerEmptyRunningItems": "Não há contêineres em execução.\nIsso pode ser porque:\n- O usuário que instalou o Docker difere do usuário configurado no app\n- A variável de ambiente DOCKER_HOST não foi lida corretamente. Você pode verificar isso executando `echo $DOCKER_HOST` no terminal.",
"dockerImagesFmt": "Total de {count} imagens",
"dockerNotInstalled": "Docker não instalado",
@@ -85,40 +47,24 @@
"dockerStatusRunningFmt": "{count} contêiner(es) em execução",
"doubleColumnMode": "Modo de coluna dupla",
"doubleColumnTip": "Esta opção apenas ativa a funcionalidade, se ela será ativada depende também da largura do dispositivo",
"download": "Baixar",
"edit": "Editar",
"editVirtKeys": "Editar teclas virtuais",
"editor": "Editor",
"editorHighlightTip": "O desempenho do destaque de código atualmente é ruim, pode optar por desativá-lo para melhorar.",
"encode": "Codificar",
"envVars": "Variável de ambiente",
"error": "Erro",
"exampleName": "Exemplo de nome",
"experimentalFeature": "Recurso experimental",
"export": "Exportar",
"extraArgs": "Argumentos extras",
"failed": "Falhou",
"fallbackSshDest": "Destino SSH de fallback",
"fdroidReleaseTip": "Se você baixou este aplicativo do F-Droid, é recomendado desativar esta opção.",
"feedback": "Feedback",
"feedbackOnGithub": "Se você tem qualquer problema, por favor, dê feedback no GitHub",
"fieldMustNotEmpty": "Estes campos não podem estar vazios.",
"fileNotExist": "{file} não existe",
"fileTooLarge": "Arquivo '{file}' muito grande '{size}', excedendo {sizeMax}",
"files": "Arquivos",
"finished": "Finalizado",
"followSystem": "Seguir sistema",
"font": "Fonte",
"fontSize": "Tamanho da fonte",
"forExample": "Por exemplo",
"force": "Forçar",
"foundNUpdate": "Encontradas {count} atualizações",
"fullScreen": "Modo tela cheia",
"fullScreenJitter": "Tremulação em tela cheia",
"fullScreenJitterHelp": "Prevenir burn-in de tela",
"fullScreenTip": "Deve ser ativado o modo de tela cheia quando o dispositivo é girado para o modo paisagem? Esta opção aplica-se apenas à aba do servidor.",
"getPushTokenFailed": "Não foi possível obter token de notificação",
"gettingToken": "Obtendo Token...",
"goBackQ": "Voltar?",
"goto": "Ir para",
"hideTitleBar": "Ocultar barra de título",
@@ -126,40 +72,26 @@
"highlight": "Destaque de código",
"homeWidgetUrlConfig": "Configuração de URL do widget da tela inicial",
"host": "Host",
"hour": "Hora",
"httpFailedWithCode": "Falha na solicitação, código de status: {code}",
"icloudSynced": "iCloud sincronizado, algumas configurações podem precisar de reinicialização do app para serem aplicadas.",
"ignoreCert": "Ignorar certificado",
"image": "Imagem",
"imagesList": "Lista de imagens",
"import": "Importar",
"inAppUpdate": "Atualizar dentro do app? Caso contrário, baixe usando um navegador.",
"init": "Inicializar",
"inner": "Interno",
"inputDomainHere": "Insira o domínio aqui",
"install": "Instalar",
"installDockerWithUrl": "Por favor, instale o Docker primeiro em https://docs.docker.com/engine/install",
"invalid": "Inválido",
"invalidJson": "JSON inválido",
"invalidVersion": "Versão não suportada",
"invalidVersionHelp": "Por favor, assegure que o Docker está corretamente instalado, ou que não está usando uma versão compilada por si mesmo. Se não houver problemas, por favor, reporte em {url}.",
"isBusy": "Ocupado no momento",
"jumpServer": "Servidor de salto",
"keepForeground": "Por favor, mantenha o app em primeiro plano!",
"keepStatusWhenErr": "Manter o status anterior do servidor",
"keepStatusWhenErrTip": "Limitado a erros de execução de scripts",
"keyAuth": "Autenticação por chave",
"language": "Idioma",
"languageName": "Português",
"lastTry": "Última tentativa",
"launchPage": "Página de lançamento",
"letterCache": "Cache de letras",
"letterCacheTip": "Recomendado desativar, mas após desativar, será impossível inserir caracteres CJK.",
"license": "Licença de código aberto",
"light": "Claro",
"loadingFiles": "Carregando diretórios...",
"location": "Localização",
"log": "Log",
"loss": "Taxa de perda",
"madeWithLove": "Feito com ❤️ por {myGithub}",
"manual": "Manual",
@@ -167,37 +99,23 @@
"maxRetryCount": "Número de tentativas de reconexão com o servidor",
"maxRetryCountEqual0": "Irá tentar indefinidamente",
"min": "Mínimo",
"minute": "Minuto",
"mission": "Missão",
"more": "Mais",
"moveOutServerFuncBtnsHelp": "Ativado: Mostra abaixo de cada cartão na aba do servidor. Desativado: Mostra no topo da página de detalhes do servidor.",
"ms": "ms",
"name": "Nome",
"needHomeDir": "Se você é usuário de Synology, [veja aqui](https://kb.synology.com/DSM/tutorial/user_enable_home_service). Usuários de outros sistemas precisam pesquisar como criar um diretório home.",
"needRestart": "Necessita reiniciar o app",
"net": "Rede",
"netViewType": "Tipo de visualização de rede",
"newContainer": "Novo contêiner",
"noClient": "Sem conexão SSH",
"noInterface": "Sem interface disponível",
"noLineChart": "Não usar gráficos de linha",
"noLineChartForCpu": "Não utilizar gráficos de linhas para a CPU",
"noNotiPerm": "Sem permissão de notificação, possivelmente sem indicação de progresso ao baixar atualizações de aplicativos.",
"noOptions": "Sem opções",
"noPrivateKeyTip": "A chave privada não existe, pode ter sido deletada ou há um erro de configuração.",
"noPromptAgain": "Não perguntar novamente",
"noResult": "Sem resultados",
"noSavedPrivateKey": "Nenhuma chave privada salva.",
"noSavedSnippet": "Nenhum snippet de código salvo.",
"noServerAvailable": "Nenhum servidor disponível.",
"noTask": "Sem tarefas",
"noUpdateAvailable": "Sem atualizações disponíveis",
"node": "Nó",
"notAvailable": "Indisponível",
"notSelected": "Não selecionado",
"note": "Nota",
"nullToken": "Token nulo",
"ok": "OK",
"onServerDetailPage": "Na página de detalhes do servidor",
"onlyOneLine": "Exibir apenas como uma linha (rolável)",
"onlyWhenCoreBiggerThan8": "Efetivo apenas quando o número de núcleos > 8",
@@ -209,7 +127,6 @@
"path": "Caminho",
"percentOfSize": "{percent}% de {size}",
"permission": "Permissões",
"pickFile": "Escolher arquivo",
"pingAvg": "Média:",
"pingInputIP": "Por favor, insira o IP ou domínio alvo",
"pingNoServer": "Nenhum servidor disponível para Ping\nPor favor, adicione um servidor na aba de servidores e tente novamente",
@@ -217,8 +134,6 @@
"pkgUpgradeTip": "Por favor, faça backup do seu sistema antes de atualizar.",
"platformNotSupportUpdate": "Atualização não suportada na plataforma atual, por favor, instale manualmente a versão mais recente do código-fonte",
"plugInType": "Tipo de Inserção",
"plzEnterHost": "Por favor, insira o host",
"plzSelectKey": "Por favor, selecione uma chave privada",
"port": "Porta",
"preview": "Pré-visualização",
"primaryColorSeed": "Semente da cor primária",
@@ -231,16 +146,11 @@
"pwd": "Senha",
"read": "Leitura",
"reboot": "Reiniciar",
"rememberChoice": "Lembrar da seleção",
"rememberPwdInMem": "Lembrar senha na memória",
"rememberPwdInMemTip": "Usado para contêineres, suspensão, etc.",
"rememberWindowSize": "Lembrar o tamanho da janela",
"remotePath": "Caminho remoto",
"rename": "Renomear",
"reportBugsOnGithubIssue": "Por favor, reporte problemas em {url}",
"restart": "Reiniciar",
"restore": "Restaurar",
"restoreSuccess": "Restauração bem-sucedida, é necessário reiniciar o app para aplicar as mudanças",
"result": "Resultado",
"rotateAngel": "Ângulo de rotação",
"route": "Roteamento",
@@ -255,12 +165,6 @@
"serverDetailOrder": "Ordem dos componentes na página de detalhes do servidor",
"serverFuncBtns": "Botões de função do servidor",
"serverOrder": "Ordem do servidor",
"serverTabConnecting": "Conectando...",
"serverTabEmpty": "Não há servidores no momento.\nClique no botão inferior direito para adicionar um.",
"serverTabFailed": "Falha",
"serverTabLoading": "Carregando...",
"serverTabPlzSave": "Por favor, salve esta chave privada novamente",
"serverTabUnkown": "Estado desconhecido",
"setting": "Configurações",
"sftpDlPrepare": "Preparando para conectar ao servidor...",
"sftpEditorTip": "Se vazio, use o editor de arquivos integrado do aplicativo. Se houver um valor, use o editor do servidor remoto, por exemplo, `vim` (recomendado detectar automaticamente de acordo com `EDITOR`).",
@@ -307,7 +211,6 @@
"trySudo": "Tentar usar sudo",
"ttl": "TTL",
"unknown": "Desconhecido",
"unknownError": "Erro desconhecido",
"unkownConvertMode": "Modo de conversão desconhecido",
"update": "Atualizar",
"updateAll": "Atualizar tudo",
@@ -318,13 +221,11 @@
"upload": "Upload",
"upsideDown": "Inverter verticalmente",
"uptime": "Tempo de atividade",
"urlOrJson": "URL ou JSON",
"useCdn": "Utilizando CDN",
"useCdnTip": "Recomenda-se que usuários não chineses usem CDN. Gostaria de usá-lo?",
"useNoPwd": "Será usado sem senha",
"usePodmanByDefault": "Usar Podman por padrão",
"used": "Usado",
"user": "Usuário",
"versionHaveUpdate": "Nova versão encontrada: v1.0.{build}, clique para atualizar",
"versionUnknownUpdate": "Versão atual: v1.0.{build}, clique para verificar atualizações",
"versionUpdated": "Versão atual: v1.0.{build}, já está atualizado",
@@ -338,7 +239,6 @@
"watchNotPaired": "Não há Apple Watch pareado",
"webdavSettingEmpty": "Configurações de Webdav estão vazias",
"whenOpenApp": "Ao abrir o app",
"willTakEeffectImmediately": "As alterações serão aplicadas imediatamente",
"wolTip": "Após configurar o WOL (Wake-on-LAN), um pedido de WOL é enviado cada vez que o servidor é conectado.",
"write": "Escrita",
"writeScriptFailTip": "Falha ao escrever no script, possivelmente devido à falta de permissões ou o diretório não existe.",

View File

@@ -3,81 +3,43 @@
"about": "о",
"aboutThanks": "Благодарности всем участникам.",
"acceptBeta": "Принять обновления тестовой версии",
"add": "добавить",
"addAServer": "добавить сервер",
"addPrivateKey": "добавить приватный ключ",
"addSystemPrivateKeyTip": "В данный момент приватные ключи отсутствуют. Добавить системный приватный ключ (~/.ssh/id_rsa)?",
"added2List": "добавлено в список задач",
"addr": "Адрес",
"all": "все",
"alreadyLastDir": "Уже в корневом каталоге",
"askContinue": "{msg}, продолжить?",
"attention": "внимание",
"authFailTip": "Аутентификация не удалась, пожалуйста, проверьте, правильны ли пароль/ключ/хост/пользователь и т.д.",
"authRequired": "требуется аутентификация",
"auto": "авто",
"autoBackupConflict": "Может быть включено только одно автоматическое резервное копирование",
"autoCheckUpdate": "автоматическая проверка обновлений",
"autoConnect": "автоматическое подключение",
"autoRun": "автозапуск",
"autoUpdateHomeWidget": "автоматическое обновление виджета на главном экране",
"backup": "резервное копирование",
"backupTip": "Экспортированные данные зашифрованы простым способом, пожалуйста, храните их в безопасности.",
"backupVersionNotMatch": "Версия резервной копии не совпадает, восстановление невозможно",
"battery": "батарея",
"bgRun": "работа в фоновом режиме",
"bgRunTip": "Этот переключатель означает, что программа будет пытаться работать в фоновом режиме, но фактическое выполнение зависит от того, включено ли разрешение. Для нативного Android отключите «Оптимизацию батареи» для этого приложения, для MIUI измените стратегию энергосбережения на «Без ограничений».",
"bioAuth": "биометрическая аутентификация",
"browser": "Браузер",
"bulkImportServers": "Пакетный импорт серверов",
"canPullRefresh": "можно обновить, потянув вниз",
"cancel": "отмена",
"choose": "выбрать",
"chooseFontFile": "выбрать файл шрифта",
"choosePrivateKey": "выбрать приватный ключ",
"clear": "очистить",
"clipboard": "буфер обмена",
"close": "закрыть",
"cmd": "команда",
"cnKeyboardComp": "Совместимость с китайским Android",
"cnKeyboardCompTip": "Если терминал отображает безопасную клавиатуру, вы можете ее активировать.",
"collapseUI": "свернуть",
"collapseUITip": "Свернуть длинные списки в UI по умолчанию",
"conn": "подключение",
"connected": "подключено",
"container": "контейнер",
"containerName": "имя контейнера",
"containerStatus": "статус контейнера",
"containerTrySudoTip": "Например: если пользователь в приложении установлен как aaa, но Docker установлен под пользователем root, тогда нужно включить эту опцию",
"content": "Содержимое",
"convert": "конвертировать",
"copy": "копировать",
"copyPath": "копировать путь",
"cpuViewAsProgressTip": "Отобразите уровень использования каждого процессора в виде индикатора выполнения (старый стиль)",
"createFile": "создать файл",
"createFolder": "создать папку",
"cursorType": "Тип курсора",
"customCmd": "Пользовательские команды",
"customCmdDocUrl": "https://github.com/lollipopkit/flutter_server_box/wiki#custom-commands",
"customCmdHint": "\"Имя команды\": \"Команда\"",
"dark": "темная",
"day": "День",
"debug": "отладка",
"decode": "декодировать",
"decompress": "разархивировать",
"delete": "удалить",
"deleteServers": "удалить серверы пакетно",
"deviceName": "Название устройства",
"dirEmpty": "Пожалуйста, убедитесь, что папка пуста",
"disabled": "отключено",
"disconnected": "отключено",
"disk": "диск",
"diskIgnorePath": "путь игнорирования диска",
"displayCpuIndex": "Показать индекс ЦПУ",
"displayName": "отображаемое имя",
"dl2Local": "Загрузить {fileName} на локальный диск?",
"doc": "Документация",
"dockerEditHost": "редактировать DOCKER_HOST",
"dockerEmptyRunningItems": "Нет запущенных контейнеров.\nЭто может быть из-за:\n- пользователя Docker, отличного от пользователя, настроенного в приложении\n- переменной окружения DOCKER_HOST, которая не была правильно считана. Вы можете выполнить `echo $DOCKER_HOST` в терминале, чтобы увидеть ее значение.",
"dockerImagesFmt": "Всего {count} образов",
"dockerNotInstalled": "Docker не установлен",
@@ -85,40 +47,24 @@
"dockerStatusRunningFmt": "{count} контейнеров запущено",
"doubleColumnMode": "режим двойной колонки",
"doubleColumnTip": "Эта опция лишь включает функцию; фактическое применение зависит от ширины устройства",
"download": "скачать",
"edit": "редактировать",
"editVirtKeys": "редактировать виртуальные клавиши",
"editor": "редактор",
"editorHighlightTip": "Текущая производительность подсветки кода неудовлетворительна, можно отключить для улучшения.",
"encode": "кодировать",
"envVars": "Переменная окружения",
"error": "ошибка",
"exampleName": "пример имени",
"experimentalFeature": "экспериментальная функция",
"export": "экспорт",
"extraArgs": "дополнительные аргументы",
"failed": "неудача",
"fallbackSshDest": "Резервное место назначения SSH",
"fdroidReleaseTip": "Если вы скачали это приложение с F-Droid, рекомендуется отключить эту опцию.",
"feedback": "обратная связь",
"feedbackOnGithub": "Если у вас есть какие-либо вопросы, пожалуйста, отправьте отзыв на GitHub",
"fieldMustNotEmpty": "Эти поля не могут быть пустыми.",
"fileNotExist": "{file} не существует",
"fileTooLarge": "Файл '{file}' слишком большой '{size}', превышает {sizeMax}",
"files": "файлы",
"finished": "завершено",
"followSystem": "следовать за системой",
"font": "шрифт",
"fontSize": "размер шрифта",
"forExample": "Например",
"force": "принудительно",
"foundNUpdate": "Найдено {count} обновлений",
"fullScreen": "полноэкранный режим",
"fullScreenJitter": "дрожание в полноэкранном режиме",
"fullScreenJitterHelp": "предотвращение выгорания экрана",
"fullScreenTip": "Следует ли включить полноэкранный режим, когда устройство поворачивается в альбомный режим? Эта опция применяется только к вкладке сервера.",
"getPushTokenFailed": "Не удалось получить токен уведомлений",
"gettingToken": "Получение токена...",
"goBackQ": "Вернуться?",
"goto": "перейти к",
"hideTitleBar": "Скрыть заголовок",
@@ -126,40 +72,26 @@
"highlight": "подсветка кода",
"homeWidgetUrlConfig": "конфигурация URL виджета домашнего экрана",
"host": "хост",
"hour": "Час",
"httpFailedWithCode": "Ошибка запроса, код: {code}",
"icloudSynced": "Синхронизация с iCloud выполнена, некоторые настройки могут потребовать перезапуска приложения для вступления в силу.",
"ignoreCert": "Игнорировать сертификат",
"image": "образ",
"imagesList": "список образов",
"import": "импорт",
"inAppUpdate": "Обновить в приложении? В противном случае загрузите с помощью браузера.",
"init": "Инициализировать",
"inner": "встроенный",
"inputDomainHere": "введите домен здесь",
"install": "установить",
"installDockerWithUrl": "Пожалуйста, сначала установите Docker по адресу https://docs.docker.com/engine/install",
"invalid": "Недействительный",
"invalidJson": "неверный JSON",
"invalidVersion": "неподдерживаемая версия",
"invalidVersionHelp": "Пожалуйста, убедитесь, что docker установлен корректно, или что используется не собственно собранная версия. Если проблема не в этом, пожалуйста, отправьте отчет о проблеме на {url}.",
"isBusy": "занято",
"jumpServer": "прыжковый сервер",
"keepForeground": "Пожалуйста, держите приложение в фокусе!",
"keepStatusWhenErr": "Сохранять статус сервера при ошибке",
"keepStatusWhenErrTip": "Применимо только в случае ошибки выполнения скрипта",
"keyAuth": "аутентификация по ключу",
"language": "язык",
"languageName": "Русский",
"lastTry": "последняя попытка",
"launchPage": "стартовая страница",
"letterCache": "Кэширование букв",
"letterCacheTip": "Рекомендуется отключить, но после отключения будет невозможно вводить символы CJK.",
"license": "лицензия",
"light": "светлая",
"loadingFiles": "Загрузка файлов...",
"location": "местоположение",
"log": "лог",
"loss": "потери пакетов",
"madeWithLove": "Создано с ❤️ by {myGithub}",
"manual": "вручную",
@@ -167,37 +99,23 @@
"maxRetryCount": "максимальное количество попыток переподключения к серверу",
"maxRetryCountEqual0": "будет бесконечно пытаться переподключиться",
"min": "минимум",
"minute": "Минута",
"mission": "задача",
"more": "больше",
"moveOutServerFuncBtnsHelp": "Включено: кнопки функций сервера отображаются под каждой карточкой на вкладке сервера. Выключено: отображается в верхней части страницы деталей сервера.",
"ms": "мс",
"name": "имя",
"needHomeDir": "Если вы пользователь Synology, [смотрите здесь](https://kb.synology.com/DSM/tutorial/user_enable_home_service). Пользователям других систем нужно искать, как создать домашний каталог.",
"needRestart": "требуется перезапуск приложения",
"net": "сеть",
"netViewType": "тип визуализации сети",
"newContainer": "создать контейнер",
"noClient": "нет SSH соединения",
"noInterface": "нет доступных интерфейсов",
"noLineChart": "Не использовать линейные графики",
"noLineChartForCpu": "Не используйте линейные графики для ЦП",
"noNotiPerm": "Нет разрешения на уведомления, возможно отсутствие индикации прогресса при загрузке обновлений приложений.",
"noOptions": "нет доступных опций",
"noPrivateKeyTip": "Приватный ключ не существует, возможно, он был удален или есть ошибка в настройках.",
"noPromptAgain": "Больше не спрашивать",
"noResult": "нет результатов",
"noSavedPrivateKey": "Нет сохраненных приватных ключей.",
"noSavedSnippet": "Нет сохраненных фрагментов кода.",
"noServerAvailable": "Нет доступных серверов.",
"noTask": "нет задач",
"noUpdateAvailable": "нет доступных обновлений",
"node": "Узел",
"notAvailable": "Недоступно",
"notSelected": "не выбрано",
"note": "заметка",
"nullToken": "нет токена",
"ok": "ок",
"onServerDetailPage": "на странице деталей сервера",
"onlyOneLine": "Отображать только в одной строке (прокручиваемо)",
"onlyWhenCoreBiggerThan8": "Действует только при количестве ядер > 8",
@@ -209,7 +127,6 @@
"path": "путь",
"percentOfSize": "{percent}% от {size}",
"permission": "Разрешения",
"pickFile": "выбрать файл",
"pingAvg": "Среднее:",
"pingInputIP": "Пожалуйста, введите целевой IP или доменное имя",
"pingNoServer": "Нет доступных серверов для Ping\nПожалуйста, добавьте серверы на вкладке серверов и попробуйте снова",
@@ -217,8 +134,6 @@
"pkgUpgradeTip": "Пожалуйста, сделайте резервную копию системы перед обновлением.",
"platformNotSupportUpdate": "Текущая платформа не поддерживает обновления, пожалуйста, вручную установите последнюю версию из исходного кода",
"plugInType": "Тип вставки",
"plzEnterHost": "Пожалуйста, введите хост",
"plzSelectKey": "Пожалуйста, выберите ключ",
"port": "порт",
"preview": "предпросмотр",
"primaryColorSeed": "основной цветовой тон",
@@ -231,16 +146,11 @@
"pwd": "пароль",
"read": "чтение",
"reboot": "перезагрузка",
"rememberChoice": "Запомнить выбор",
"rememberPwdInMem": "Запомнить пароль в памяти",
"rememberPwdInMemTip": "Используется для контейнеров, приостановки и т. д.",
"rememberWindowSize": "Запомнить размер окна",
"remotePath": "удаленный путь",
"rename": "переименовать",
"reportBugsOnGithubIssue": "Пожалуйста, сообщайте о проблемах на {url}",
"restart": "перезапустить",
"restore": "восстановить",
"restoreSuccess": "Восстановление успешно, требуется перезапуск приложения для применения изменений",
"result": "результат",
"rotateAngel": "угол поворота",
"route": "Маршрутизация",
@@ -255,12 +165,6 @@
"serverDetailOrder": "порядок элементов на странице деталей сервера",
"serverFuncBtns": "кнопки функций сервера",
"serverOrder": "порядок серверов",
"serverTabConnecting": "подключение...",
"serverTabEmpty": "Серверов пока нет.\nНажмите кнопку в правом нижнем углу, чтобы добавить.",
"serverTabFailed": "ошибка",
"serverTabLoading": "загрузка...",
"serverTabPlzSave": "Пожалуйста, сохраните этот приватный ключ еще раз",
"serverTabUnkown": "неизвестно",
"setting": "настройки",
"sftpDlPrepare": "Подготовка к подключению к серверу...",
"sftpEditorTip": "Если пусто, используйте встроенный редактор файлов приложения. Если значение указано, используйте редактор удаленного сервера, например, `vim` (рекомендуется автоматически определять согласно `EDITOR`).",
@@ -307,7 +211,6 @@
"trySudo": "попробовать использовать sudo",
"ttl": "TTL",
"unknown": "неизвестно",
"unknownError": "неизвестная ошибка",
"unkownConvertMode": "неизвестный режим конвертации",
"update": "обновление",
"updateAll": "обновить все",
@@ -318,13 +221,11 @@
"upload": "загрузить",
"upsideDown": "перевернуть",
"uptime": "время работы",
"urlOrJson": "ссылка или JSON",
"useCdn": "Использование CDN",
"useCdnTip": "Не китайским пользователям рекомендуется использовать CDN. Хотели бы вы его использовать?",
"useNoPwd": "будет использоваться без пароля",
"usePodmanByDefault": "использовать Podman по умолчанию",
"used": "использовано",
"user": "пользователь",
"versionHaveUpdate": "Найдена новая версия: v1.0.{build}, нажмите для обновления",
"versionUnknownUpdate": "Текущая: v1.0.{build}, нажмите для проверки обновлений",
"versionUpdated": "Текущая: v1.0.{build}, последняя версия",
@@ -338,7 +239,6 @@
"watchNotPaired": "Apple Watch не сопряжены",
"webdavSettingEmpty": "Настройки Webdav пусты",
"whenOpenApp": "при открытии приложения",
"willTakEeffectImmediately": "Изменения вступят в силу немедленно",
"wolTip": "После настройки WOL (Wake-on-LAN) при каждом подключении к серверу отправляется запрос WOL.",
"write": "запись",
"writeScriptFailTip": "Запись в скрипт не удалась, возможно, из-за отсутствия прав или директории не существует.",

View File

@@ -3,81 +3,43 @@
"about": "Hakkında",
"aboutThanks": "Katılım gösteren aşağıdaki kişilere teşekkür ederiz.",
"acceptBeta": "Beta sürüm güncellemelerini kabul et",
"add": "Ekle",
"addAServer": "Sunucu ekle",
"addPrivateKey": "Özel anahtar ekle",
"addSystemPrivateKeyTip": "Şu anda özel anahtar yok, sistemle geleni (~/.ssh/id_rsa) eklemek ister misiniz?",
"added2List": "Görev listesine eklendi",
"addr": "Adres",
"all": "Tümü",
"alreadyLastDir": "Zaten son klasörde.",
"askContinue": "{msg}. Devam edilsin mi?",
"attention": "Dikkat",
"authFailTip": "Kimlik doğrulama başarısız, kimlik bilgilerinin doğru olup olmadığını kontrol edin",
"authRequired": "Kimlik doğrulama gerekli",
"auto": "Otomatik",
"autoBackupConflict": "Aynı anda yalnızca bir otomatik yedekleme etkinleştirilebilir.",
"autoCheckUpdate": "Otomatik güncelleme kontrolü",
"autoConnect": "Otomatik bağlan",
"autoRun": "Otomatik çalıştır",
"autoUpdateHomeWidget": "Ana widget'ı otomatik güncelle",
"backup": "Yedekleme",
"backupTip": "Dışa aktarılan veriler zayıf bir şekilde şifrelenmiştir. \nLütfen güvenli bir yerde saklayın.",
"backupVersionNotMatch": "Yedekleme sürümü uyumlu değil.",
"battery": "Pil",
"bgRun": "Arka planda çalıştır",
"bgRunTip": "Bu anahtar yalnızca programın arka planda çalışmayı deneyeceğini ifade eder. Arka planda çalışıp çalışamayacağı, iznin etkinleştirilip etkinleştirilmediğine bağlıdır. AOSP tabanlı Android ROM'larda, bu uygulamada \"Pil Optimizasyonunu\" devre dışı bırakın. MIUI / HyperOS için, güç tasarrufu politikasını \"Sınırsız\" olarak değiştirin.",
"bioAuth": "Biyometrik kimlik doğrulama",
"browser": "Tarayıcı",
"bulkImportServers": "Toplu sunucu içe aktarma",
"canPullRefresh": "Yenilemek için aşağı çekebilirsiniz.",
"cancel": "İptal",
"choose": "Seç",
"chooseFontFile": "Yazı tipi dosyası seçin",
"choosePrivateKey": "Özel anahtar seç",
"clear": "Temizle",
"clipboard": "Panoya kopyala",
"close": "Kapat",
"cmd": "Komut",
"cnKeyboardComp": "Çin Android uyumluluğu",
"cnKeyboardCompTip": "Terminalde güvenli bir klavye açılırsa, bunu etkinleştirebilirsiniz.",
"collapseUI": "Gizle",
"collapseUITip": "UI'daki uzun listeleri varsayılan olarak gizleyip gizlememeyi belirler",
"conn": "Bağlantı",
"connected": "Bağlı",
"container": "Konteyner",
"containerName": "Konteyner adı",
"containerStatus": "Konteyner durumu",
"containerTrySudoTip": "Örneğin: Uygulamada kullanıcı aaa olarak ayarlanmış, ancak Docker root kullanıcısı altında kurulmuş. Bu durumda, bu seçeneği etkinleştirmeniz gerekir.",
"content": "İçerik",
"convert": "Dönüştür",
"copy": "Kopyala",
"copyPath": "Yolu kopyala",
"cpuViewAsProgressTip": "Her CPU'nun kullanımını bir ilerleme çubuğu tarzında görüntüle (eski tarz)",
"createFile": "Dosya oluştur",
"createFolder": "Klasör oluştur",
"cursorType": "İmleç türü",
"customCmd": "Özel komutlar",
"customCmdDocUrl": "https://github.com/lollipopkit/flutter_server_box/wiki#custom-commands",
"customCmdHint": "\"Komut Adı\": \"Komut\"",
"dark": "Karanlık",
"day": "Gün",
"debug": "Hata ayıklama",
"decode": "Çöz",
"decompress": "Sıkıştırmayı aç",
"delete": "Sil",
"deleteServers": "Toplu sunucu silme",
"deviceName": "Cihaz adı",
"dirEmpty": "Klasörün boş olduğundan emin olun.",
"disabled": "Devre dışı",
"disconnected": "Bağlantı kesildi",
"disk": "Disk",
"diskIgnorePath": "Disk için göz ardı edilen yol",
"displayCpuIndex": "CPU dizinini görüntüle",
"displayName": "Görünen ad",
"dl2Local": "{fileName} dosyasını yerel olarak indirmek istiyor musunuz?",
"doc": "Dokümantasyon",
"dockerEditHost": "DOCKER_HOST'u düzenle",
"dockerEmptyRunningItems": "Çalışan konteyner yok.\nBu şu sebeplerden kaynaklanabilir:\n- Docker kurulumu kullanıcı adı, uygulamada yapılandırılan kullanıcı adıyla aynı değil.\n- DOCKER_HOST ortam değişkeni doğru okunmadı. Terminalde `echo $DOCKER_HOST` komutunu çalıştırarak elde edebilirsiniz.",
"dockerImagesFmt": "{count} görüntü",
"dockerNotInstalled": "Docker kurulu değil",
@@ -85,40 +47,24 @@
"dockerStatusRunningFmt": "{count} konteyner çalışıyor.",
"doubleColumnMode": "Çift sütun modu",
"doubleColumnTip": "Bu seçenek yalnızca özelliği etkinleştirir, gerçekten etkinleştirilebilir olup olmadığını cihazın genişliği belirler",
"download": "İndir",
"edit": "Düzenle",
"editVirtKeys": "Sanal tuşları düzenle",
"editor": "Editör",
"editorHighlightTip": "Mevcut kod vurgulama performansı ideal değil ve isteğe bağlı olarak kapatılabilir.",
"encode": "Kodla",
"envVars": "Ortam değişkeni",
"error": "Hata",
"exampleName": "Örnek adı",
"experimentalFeature": "Deneysel özellik",
"export": "Dışa aktar",
"extraArgs": "Ek argümanlar",
"failed": "Başarısız",
"fallbackSshDest": "Yedek SSH hedefi",
"fdroidReleaseTip": "Bu uygulamayı F-Droid'den indirdiyseniz, bu seçeneği kapatmanız önerilir.",
"feedback": "Geri bildirim",
"feedbackOnGithub": "Sorularınız varsa, lütfen Github'da sorun oluşturun.",
"fieldMustNotEmpty": "Bu alanlar boş olamaz.",
"fileNotExist": "{file} mevcut değil",
"fileTooLarge": "'{file}' dosyası çok büyük {size}, maksimum {sizeMax}",
"files": "Dosyalar",
"finished": "Tamamlandı",
"followSystem": "Sistemi takip et",
"font": "Yazı tipi",
"fontSize": "Yazı tipi boyutu",
"forExample": "Örneğin",
"force": "Zorla",
"foundNUpdate": "{count} güncelleme bulundu",
"fullScreen": "Tam ekran modu",
"fullScreenJitter": "Tam ekran titremesi",
"fullScreenJitterHelp": "Ekran yanıklarını önlemek için",
"fullScreenTip": "Cihaz yatay moda döndürüldüğünde tam ekran modu etkinleştirilsin mi? Bu seçenek yalnızca sunucu sekmesi için geçerlidir.",
"getPushTokenFailed": "Push token alınamıyor",
"gettingToken": "Token alınıyor...",
"goBackQ": "Geri dön?",
"goto": "Git",
"hideTitleBar": "Başlık çubuğunu gizle",
@@ -126,40 +72,26 @@
"highlight": "Kod vurgulama",
"homeWidgetUrlConfig": "Ana sayfa widget URL'sini yapılandır",
"host": "Sunucu",
"hour": "Saat",
"httpFailedWithCode": "İstek başarısız oldu, durum kodu: {code}",
"icloudSynced": "iCloud senkronize ediliyor ve bazı ayarlar uygulamanın yeniden başlatılmasını gerektirebilir.",
"ignoreCert": "Sertifikayı yoksay",
"image": "Resim",
"imagesList": "Resim listesi",
"import": "İçe aktar",
"inAppUpdate": "Uygulama içinde güncelle? Aksi takdirde, bir tarayıcı kullanarak indirin.",
"init": "Başlat",
"inner": "İç",
"inputDomainHere": "Buraya etki alanı girin",
"install": "Kur",
"installDockerWithUrl": "Lütfen önce Docker'ı https://docs.docker.com/engine/install adresinden kurun.",
"invalid": "Geçersiz",
"invalidJson": "Geçersiz JSON",
"invalidVersion": "Geçersiz sürüm",
"invalidVersionHelp": "Lütfen Docker'ın doğru şekilde kurulduğundan emin olun veya kendi derlemediğiniz bir sürüm kullandığınızdan emin olun. Yukarıdaki sorunlardan herhangi biri yoksa, lütfen {url} adresine bir sorun gönderin.",
"isBusy": "Şu anda meşgul",
"jumpServer": "Atlama sunucusu",
"keepForeground": "Uygulama ön planda kalsın!",
"keepStatusWhenErr": "Son sunucu durumunu koru",
"keepStatusWhenErrTip": "Yalnızca betik yürütme sırasında bir hata oluştuğunda",
"keyAuth": "Anahtar Doğrulama",
"language": "Dil",
"languageName": "Türkçe",
"lastTry": "Son deneme",
"launchPage": "Başlangıç sayfası",
"letterCache": "Harf önbelleği",
"letterCacheTip": "Devre dışı bırakılması önerilir, ancak devre dışı bırakıldıktan sonra CJK karakterleri girilemez.",
"license": "Lisans",
"light": "Açık",
"loadingFiles": "Dosyalar yükleniyor...",
"location": "Konum",
"log": "Kayıt",
"loss": "kayıp",
"madeWithLove": "{myGithub} tarafından ❤️ ile yapıldı",
"manual": "Kılavuz",
@@ -167,37 +99,23 @@
"maxRetryCount": "Sunucu yeniden bağlanma sayısı",
"maxRetryCountEqual0": "Sürekli olarak tekrar denenecek.",
"min": "min",
"minute": "Dakika",
"mission": "Görev",
"more": "Daha fazla",
"moveOutServerFuncBtnsHelp": "Açık: Sunucu sekmesi sayfasındaki her kartın altında görüntülenebilir. Kapalı: Sunucu Detayları sayfasının üst kısmında görüntülenebilir.",
"ms": "ms",
"name": "İsim",
"needHomeDir": "Synology kullanıcısıysanız, [buraya bakın](https://kb.synology.com/DSM/tutorial/user_enable_home_service). Diğer sistem kullanıcılarının bir ana dizin oluşturmayı öğrenmeleri gerekir.",
"needRestart": "Uygulamanın yeniden başlatılması gerekiyor",
"net": "Ağ",
"netViewType": "Ağ görünümü türü",
"newContainer": "Yeni konteyner",
"noClient": "İstemci yok",
"noInterface": "Arayüz yok",
"noLineChart": "Çizgi grafik kullanma",
"noLineChartForCpu": "CPU için çizgi grafik kullanma",
"noNotiPerm": "Bildirim izinleri yok, uygulama güncellemelerini indirirken ilerleme belirtisi olmayabilir.",
"noOptions": "Seçenek yok",
"noPrivateKeyTip": "Özel anahtar mevcut değil, silinmiş olabilir veya bir yapılandırma hatası vardır.",
"noPromptAgain": "Tekrar hatırlatma",
"noResult": "Sonuç yok",
"noSavedPrivateKey": "Kaydedilmiş özel anahtar yok.",
"noSavedSnippet": "Kaydedilmiş kesit yok.",
"noServerAvailable": "Kullanılabilir sunucu yok.",
"noTask": "Görev yok",
"noUpdateAvailable": "Güncelleme yok",
"node": "Düğüm",
"notAvailable": "Kullanılamaz",
"notSelected": "Seçili değil",
"note": "Not",
"nullToken": "Boş token",
"ok": "Tamam",
"onServerDetailPage": "Sunucu detay sayfasında",
"onlyOneLine": "Yalnızca bir satır olarak göster (kaydırılabilir)",
"onlyWhenCoreBiggerThan8": "Yalnızca çekirdek sayısı 8'den fazla olduğunda çalışır",
@@ -209,7 +127,6 @@
"path": "Yol",
"percentOfSize": "{size}'nin %{percent}'i",
"permission": "İzinler",
"pickFile": "Dosya seç",
"pingAvg": "Ortalama:",
"pingInputIP": "Lütfen bir hedef IP / etki alanı girin.",
"pingNoServer": "Ping yapılacak sunucu yok.\nLütfen sunucu sekmesine bir sunucu ekleyin.",
@@ -217,8 +134,6 @@
"pkgUpgradeTip": "Güncellemeden önce sisteminizi yedekleyin.",
"platformNotSupportUpdate": "Mevcut platform uygulama içi güncellemeyi desteklemiyor.\nLütfen kaynaktan oluşturun ve yükleyin.",
"plugInType": "Takma Türü",
"plzEnterHost": "Lütfen sunucu girin.",
"plzSelectKey": "Lütfen bir anahtar seçin.",
"port": "Port",
"preview": "Önizleme",
"primaryColorSeed": "Birincil renk tohumu",
@@ -231,16 +146,11 @@
"pwd": "Şifre",
"read": "Oku",
"reboot": "Yeniden başlat",
"rememberChoice": "Seçimi hatırla",
"rememberPwdInMem": "Şifreyi bellekte sakla",
"rememberPwdInMemTip": "Konteynerler, askıya alma vb. için kullanılır.",
"rememberWindowSize": "Pencere boyutunu hatırla",
"remotePath": "Uzak yol",
"rename": "Yeniden adlandır",
"reportBugsOnGithubIssue": "Lütfen hataları {url} adresine bildirin",
"restart": "Yeniden başlat",
"restore": "Geri yükle",
"restoreSuccess": "Geri yükleme başarılı. Uygulamanın etkili olması için yeniden başlatın.",
"result": "Sonuç",
"rotateAngel": "Dönme açısı",
"route": "Yönlendirme",
@@ -255,12 +165,6 @@
"serverDetailOrder": "Ayrıntı sayfası widget sırası",
"serverFuncBtns": "Sunucu işlev düğmeleri",
"serverOrder": "Sunucu sırası",
"serverTabConnecting": "Bağlanıyor...",
"serverTabEmpty": "Sunucu yok.\nBir tane eklemek için fab'ı tıklayın.",
"serverTabFailed": "Başarısız oldu",
"serverTabLoading": "Yükleniyor...",
"serverTabPlzSave": "Lütfen bu özel anahtarı tekrar 'kaydedin'.",
"serverTabUnkown": "Bilinmeyen durum",
"setting": "Ayarlar",
"sftpDlPrepare": "Bağlantı hazırlığı yapılıyor...",
"sftpEditorTip": "Boşsa, uygulamanın yerleşik dosya düzenleyicisini kullanın. Bir değer varsa, uzak sunucunun düzenleyicisini kullanın, örneğin, `vim` (otomatik olarak `EDITOR`'a göre algılamanız önerilir).",
@@ -307,7 +211,6 @@
"trySudo": "Sudo kullanmayı deneyin",
"ttl": "TTL",
"unknown": "Bilinmeyen",
"unknownError": "Bilinmeyen hata",
"unkownConvertMode": "Bilinmeyen dönüştürme modu",
"update": "Güncelle",
"updateAll": "Tümünü güncelle",
@@ -318,13 +221,11 @@
"upload": "Yükle",
"upsideDown": "Ters",
"uptime": "Çalışma süresi",
"urlOrJson": "URL veya JSON",
"useCdn": "CDN kullanılıyor",
"useCdnTip": "Çin dışındaki kullanıcıların CDN kullanması önerilir. Kullanmak ister misiniz?",
"useNoPwd": "Şifre kullanılmayacak",
"usePodmanByDefault": "Varsayılan olarak Podman kullan",
"used": "Kullanıldı",
"user": "Kullanıcı",
"versionHaveUpdate": "Bulundu: v1.0.{build}, güncellemek için tıklayın",
"versionUnknownUpdate": "Mevcut: v1.0.{build}, güncellemeleri kontrol etmek için tıklayın",
"versionUpdated": "Mevcut: v1.0.{build}, güncel",
@@ -338,7 +239,6 @@
"watchNotPaired": "Eşlenmiş Apple Watch yok",
"webdavSettingEmpty": "WebDav ayarı boş",
"whenOpenApp": "Uygulamayı açarken",
"willTakEeffectImmediately": "Hemen etkili olacaktır",
"wolTip": "WOL (Wake-on-LAN) yapılandırıldıktan sonra, her sunucuya bağlandığınızda bir WOL isteği gönderilir.",
"write": "Yaz",
"writeScriptFailTip": "Komut dosyasına yazma başarısız oldu, muhtemelen izin eksikliğinden veya dizin mevcut olmadığından kaynaklanıyor olabilir.",

View File

@@ -3,81 +3,43 @@
"about": "关于",
"aboutThanks": "感谢以下参与的各位。",
"acceptBeta": "接受测试版更新推送",
"add": "新增",
"addAServer": "添加服务器",
"addPrivateKey": "添加私钥",
"addSystemPrivateKeyTip": "当前没有任何私钥,是否添加系统自带的(~/.ssh/id_rsa",
"added2List": "已添加至任务列表",
"addr": "地址",
"all": "所有",
"alreadyLastDir": "已经是最上层目录了",
"askContinue": "{msg},继续吗?",
"attention": "注意",
"authFailTip": "认证失败,请检查密码/密钥/主机/用户等是否错误",
"authRequired": "需要认证",
"auto": "自动",
"autoBackupConflict": "只能同时开启一个自动备份",
"autoCheckUpdate": "自动检查更新",
"autoConnect": "自动连接",
"autoRun": "自动运行",
"autoUpdateHomeWidget": "自动更新桌面小部件",
"backup": "备份",
"backupTip": "导出的数据仅进行了简单加密,请妥善保管。",
"backupVersionNotMatch": "备份版本不匹配,无法恢复",
"battery": "电池",
"bgRun": "后台运行",
"bgRunTip": "此开关只代表程序会尝试在后台运行,具体能否后台运行取决于是否开启了权限。原生 Android 请关闭本 App 的“电池优化”MIUI / HyperOS 请修改省电策略为“无限制”。",
"bioAuth": "生物认证",
"browser": "浏览器",
"bulkImportServers": "批量导入服务器",
"canPullRefresh": "可以下拉刷新",
"cancel": "取消",
"choose": "选择",
"chooseFontFile": "选择字体文件",
"choosePrivateKey": "选择私钥",
"clear": "清除",
"clipboard": "剪切板",
"close": "关闭",
"cmd": "命令",
"cnKeyboardComp": "中国 Android 兼容性",
"cnKeyboardCompTip": "如果终端弹出安全键盘,可以开启",
"collapseUI": "折叠",
"collapseUITip": "是否默认折叠 UI 中的长列表",
"conn": "连接",
"connected": "已连接",
"container": "容器",
"containerName": "容器名",
"containerStatus": "容器状态",
"containerTrySudoTip": "例如:在应用内将用户设置为 aaa但是 Docker 安装在root用户下这时就需要启用此选项",
"content": "内容",
"convert": "转换",
"copy": "复制",
"copyPath": "复制路径",
"cpuViewAsProgressTip": "以进度条样式显示每个 CPU 的使用率(旧版样式)",
"createFile": "创建文件",
"createFolder": "创建文件夹",
"cursorType": "光标类型",
"customCmd": "自定义命令",
"customCmdDocUrl": "https://github.com/lollipopkit/flutter_server_box/wiki/主页#自定义命令",
"customCmdHint": "\"命令名称\": \"命令\"",
"dark": "暗",
"day": "天",
"debug": "调试",
"decode": "解码",
"decompress": "解压缩",
"delete": "删除",
"deleteServers": "批量删除服务器",
"deviceName": "设备名",
"dirEmpty": "请确保文件夹为空",
"disabled": "已禁用",
"disconnected": "连接断开",
"disk": "磁盘",
"diskIgnorePath": "忽略的磁盘路径",
"displayCpuIndex": "显示 CPU 索引",
"displayName": "显示名称",
"dl2Local": "下载 {fileName} 到本地?",
"doc": "文档",
"dockerEditHost": "编辑 DOCKER_HOST",
"dockerEmptyRunningItems": "没有正在运行的容器。\n这可能是因为\n- Docker 安装用户与 App 内配置的用户名不同\n- 环境变量 DOCKER_HOST 没有被正确读取。可以通过在终端内运行 `echo $DOCKER_HOST` 来获取。",
"dockerImagesFmt": "共 {count} 个镜像",
"dockerNotInstalled": "Docker 未安装",
@@ -85,40 +47,24 @@
"dockerStatusRunningFmt": "{count} 个容器正在运行",
"doubleColumnMode": "双列模式",
"doubleColumnTip": "此选项仅开启功能,实际是否能开启还取决于设备的宽度",
"download": "下载",
"edit": "编辑",
"editVirtKeys": "编辑虚拟按键",
"editor": "编辑器",
"editorHighlightTip": "目前的代码高亮性能较为糟糕,可以选择关闭以改善。",
"encode": "编码",
"envVars": "环境变量",
"error": "错误",
"exampleName": "名称示例",
"experimentalFeature": "实验性功能",
"export": "导出",
"extraArgs": "额外参数",
"failed": "失败",
"fallbackSshDest": "备选 SSH 目标",
"fdroidReleaseTip": "如果你是从 F-Droid 下载的本应用,推荐关闭此选项",
"feedback": "反馈",
"feedbackOnGithub": "如果你有任何问题请在GitHub反馈",
"fieldMustNotEmpty": "这些输入框不能为空。",
"fileNotExist": "{file} 不存在",
"fileTooLarge": "文件 '{file}' 过大 '{size}',超过了 {sizeMax}",
"files": "文件",
"finished": "已完成",
"followSystem": "跟随系统",
"font": "字体",
"fontSize": "字体大小",
"forExample": "例如",
"force": "强制",
"foundNUpdate": "找到 {count} 个更新",
"fullScreen": "全屏模式",
"fullScreenJitter": "全屏模式抖动",
"fullScreenJitterHelp": "防止烧屏",
"fullScreenTip": "当设备旋转为横屏时,是否开启全屏模式。此选项仅作用于服务器 Tab 页。",
"getPushTokenFailed": "未能获取到推送 token",
"gettingToken": "正在获取 Token...",
"goBackQ": "返回?",
"goto": "前往",
"hideTitleBar": "隐藏标题栏",
@@ -126,40 +72,26 @@
"highlight": "代码高亮",
"homeWidgetUrlConfig": "桌面部件链接配置",
"host": "主机",
"hour": "小时",
"httpFailedWithCode": "请求失败, 状态码: {code}",
"icloudSynced": "iCloud 已同步,某些设置可能需要重启才能生效。",
"ignoreCert": "忽略证书",
"image": "镜像",
"imagesList": "镜像列表",
"import": "导入",
"inAppUpdate": "在 App 内更新?否则使用浏览器下载",
"init": "初始化",
"inner": "内置",
"inputDomainHere": "在这里输入域名",
"install": "安装",
"installDockerWithUrl": "请先 https://docs.docker.com/engine/install docker",
"invalid": "无效",
"invalidJson": "无效的 JSON",
"invalidVersion": "不支持的版本",
"invalidVersionHelp": "请确保正确安装了 docker或者使用的非自编译版本。如果没有以上问题请在 {url} 提交问题。",
"isBusy": "当前正忙",
"jumpServer": "跳板服务器",
"keepForeground": "请保持应用处于前台!",
"keepStatusWhenErr": "保留上次的服务器状态",
"keepStatusWhenErrTip": "仅限于执行脚本出错",
"keyAuth": "密钥认证",
"language": "语言",
"languageName": "简体中文",
"lastTry": "最后尝试",
"launchPage": "启动页",
"letterCache": "输入法字符缓存",
"letterCacheTip": "推荐关闭,但是关闭后无法输入 CJK 等文字",
"license": "开源许可证",
"light": "亮",
"loadingFiles": "正在加载目录。。。",
"license": "证",
"location": "位置",
"log": "日志",
"loss": "丢包率",
"madeWithLove": "用❤️制作 by {myGithub}",
"manual": "手动",
@@ -167,37 +99,23 @@
"maxRetryCount": "服务器尝试重连次数",
"maxRetryCountEqual0": "会无限重试",
"min": "最小",
"minute": "分钟",
"mission": "任务",
"more": "更多",
"moveOutServerFuncBtnsHelp": "开启:可以在服务器 Tab 页的每个卡片下方显示。关闭:在服务器详情页顶部显示。",
"ms": "毫秒",
"name": "名称",
"needHomeDir": "如果你是群晖用户,[看这里](https://kb.synology.cn/zh-cn/DSM/tutorial/ssh_could_not_chdir_to_home_directory)。其他系统用户需搜索如何创建家目录home directory.",
"needRestart": "需要重启 App",
"net": "网络",
"netViewType": "网络视图类型",
"newContainer": "新建容器",
"noClient": "没有 SSH 连接",
"noInterface": "没有可用的接口",
"noLineChart": "不使用折线图",
"noLineChartForCpu": "CPU 不使用折线图",
"noNotiPerm": "无通知权限,可能下载 App 更新时无进度提示。",
"noOptions": "无可选项",
"noPrivateKeyTip": "私钥不存在,可能已被删除/配置错误",
"noPromptAgain": "不再提示",
"noResult": "无结果",
"noSavedPrivateKey": "没有已保存的私钥。",
"noSavedSnippet": "没有已保存的代码片段。",
"noServerAvailable": "没有可用的服务器。",
"noTask": "没有任务",
"noUpdateAvailable": "没有可用更新",
"node": "节点",
"notAvailable": "不可用",
"notSelected": "未选择",
"note": "备注",
"nullToken": "无 Token",
"ok": "好",
"onServerDetailPage": "在服务器详情页",
"onlyOneLine": "仅显示为一行(可滚动)",
"onlyWhenCoreBiggerThan8": "仅当核心数大于 8 时生效",
@@ -209,7 +127,6 @@
"path": "路径",
"percentOfSize": "{size} 的 {percent}%",
"permission": "权限",
"pickFile": "选择文件",
"pingAvg": "平均:",
"pingInputIP": "请输入目标IP或域名",
"pingNoServer": "没有服务器可用于 Ping\n请在服务器 tab 添加服务器后再试",
@@ -217,8 +134,6 @@
"pkgUpgradeTip": "请在更新前备份系统。",
"platformNotSupportUpdate": "当前平台不支持更新,请编译最新源码后手动安装",
"plugInType": "插入类型",
"plzEnterHost": "请输入主机",
"plzSelectKey": "请选择私钥",
"port": "端口",
"preview": "预览",
"primaryColorSeed": "主题色种子",
@@ -231,16 +146,11 @@
"pwd": "密码",
"read": "读",
"reboot": "重启",
"rememberChoice": "记住选择",
"rememberPwdInMem": "在内存中记住密码",
"rememberPwdInMemTip": "用于容器、挂起等",
"rememberWindowSize": "记住窗口大小",
"remotePath": "远端路径",
"rename": "重命名",
"reportBugsOnGithubIssue": "请到 {url} 提交问题",
"restart": "重启",
"restore": "恢复",
"restoreSuccess": "恢复成功,需要重启 App 来应用更改",
"result": "结果",
"rotateAngel": "旋转角度",
"route": "路由",
@@ -255,12 +165,6 @@
"serverDetailOrder": "详情页部件顺序",
"serverFuncBtns": "服务器功能按钮",
"serverOrder": "服务器顺序",
"serverTabConnecting": "连接中...",
"serverTabEmpty": "现在没有服务器。\n点击右下方按钮来添加。",
"serverTabFailed": "失败",
"serverTabLoading": "加载中...",
"serverTabPlzSave": "请再次保存该私钥",
"serverTabUnkown": "未知状态",
"setting": "设置",
"sftpDlPrepare": "准备连接至服务器...",
"sftpEditorTip": "如果为空, 使用App内置的文件编辑器. 如果有值, 这是用远程服务器的编辑器, 例如 `vim` (建议根据 `EDITOR` 自动获取).",
@@ -307,7 +211,6 @@
"trySudo": "尝试使用 sudo",
"ttl": "TTL",
"unknown": "未知",
"unknownError": "未知错误",
"unkownConvertMode": "未知转换模式",
"update": "更新",
"updateAll": "更新全部",
@@ -318,13 +221,11 @@
"upload": "上传",
"upsideDown": "上下交换",
"uptime": "启动时长",
"urlOrJson": "链接或 JSON",
"useCdn": "使用 CDN",
"useCdnTip": "非中国大陆用户推荐使用 CDN是否使用",
"useNoPwd": "将会使用无密码",
"usePodmanByDefault": "默认使用 Podman",
"used": "已用",
"user": "用户",
"versionHaveUpdate": "找到新版本v1.0.{build}, 点击更新",
"versionUnknownUpdate": "当前v1.0.{build},点击检查更新",
"versionUpdated": "当前v1.0.{build}, 已是最新版本",
@@ -338,7 +239,6 @@
"watchNotPaired": "没有已配对的 Apple Watch",
"webdavSettingEmpty": "WebDav 设置项为空",
"whenOpenApp": "当打开 App 时",
"willTakEeffectImmediately": "更改将会立即生效",
"wolTip": "在配置 WOL 后,每次连接服务器都会先发送一次 WOL 请求",
"write": "写",
"writeScriptFailTip": "写入脚本失败,可能是没有权限/目录不存在等",

View File

@@ -3,81 +3,43 @@
"about": "關於",
"aboutThanks": "感謝以下參與的各位。",
"acceptBeta": "接受測試版更新推送",
"add": "新增",
"addAServer": "新增伺服器",
"addPrivateKey": "新增私鑰",
"addSystemPrivateKeyTip": "當前沒有任何私鑰,是否添加系統自帶的 (~/.ssh/id_rsa)",
"added2List": "已添加至任務列表",
"addr": "位址",
"all": "所有",
"alreadyLastDir": "已經是最上層目錄了",
"askContinue": "{msg},繼續嗎?",
"attention": "注意",
"authFailTip": "認證失敗,請檢查密碼/密鑰/主機/用戶等是否錯誤。",
"authRequired": "需要認證",
"auto": "自動",
"autoBackupConflict": "只能同時開啓一個自動備份",
"autoCheckUpdate": "自動檢查更新",
"autoConnect": "自動連接",
"autoRun": "自動運行",
"autoUpdateHomeWidget": "自動更新桌面小部件",
"backup": "備份",
"backupTip": "匯出的資料僅進行了簡單加密,請妥善保管。",
"backupVersionNotMatch": "備份版本不匹配,無法還原",
"battery": "電池",
"bgRun": "後台運行",
"bgRunTip": "此開關只代表程式會嘗試在後台運行,具體能否在後臺運行取決於是否開啟了權限。 原生 Android 請關閉本 App 的“電池優化”MIUI / HyperOS 請修改省電策略為“無限制”。",
"bioAuth": "生物認證",
"browser": "瀏覽器",
"bulkImportServers": "批量導入伺服器",
"canPullRefresh": "可以下拉更新",
"cancel": "取消",
"choose": "選擇",
"chooseFontFile": "選擇字型檔",
"choosePrivateKey": "選擇私鑰",
"clear": "清除",
"clipboard": "剪貼簿",
"close": "關閉",
"cmd": "命令",
"cnKeyboardComp": "中國 Android 兼容性",
"cnKeyboardCompTip": "如果終端彈出安全鍵盤,您可以啟用它。",
"collapseUI": "折疊",
"collapseUITip": "是否預設折疊 UI 中存在的長列表",
"conn": "連接",
"connected": "已連接",
"container": "容器",
"containerName": "容器名稱",
"containerStatus": "容器狀態",
"containerTrySudoTip": "例如App 內設置使用者為 aaa但是 Docker 安裝在 root 使用者,這時就需要開啟此選項",
"content": "內容",
"convert": "轉換",
"copy": "複製",
"copyPath": "複製路徑",
"cpuViewAsProgressTip": "以進度條樣式顯示每個CPU的使用率舊版樣式",
"createFile": "創建檔案",
"createFolder": "創建資料夾",
"cursorType": "游標類型",
"customCmd": "自訂命令",
"customCmdDocUrl": "https://github.com/lollipopkit/flutter_server_box/wiki/主页#自定义命令",
"customCmdHint": "\"命令名稱\": \"命令\"",
"dark": "暗",
"day": "亮",
"debug": "除錯",
"decode": "解碼",
"decompress": "解壓縮",
"delete": "刪除",
"deleteServers": "批量刪除伺服器",
"deviceName": "設備名",
"dirEmpty": "請確保資料夾為空",
"disabled": "已禁用",
"disconnected": "連接斷開",
"disk": "磁碟",
"diskIgnorePath": "忽略的磁碟路徑",
"displayCpuIndex": "顯示 CPU 索引",
"displayName": "顯示名稱",
"dl2Local": "下載 {fileName} 到本地?",
"doc": "文檔",
"dockerEditHost": "編輯 DOCKER_HOST",
"dockerEmptyRunningItems": "沒有正在運行的容器。\n這可能是因為\n- Docker 安裝使用者與 App 內配置的使用者名稱不同\n- 環境變量 DOCKER_HOST 沒有被正確讀取。你可以通過在終端內運行 `echo $DOCKER_HOST` 來獲取。",
"dockerImagesFmt": "共 {count} 個鏡像",
"dockerNotInstalled": "Docker 未安裝",
@@ -85,40 +47,24 @@
"dockerStatusRunningFmt": "{count} 個容器正在運行",
"doubleColumnMode": "雙列模式",
"doubleColumnTip": "此選項僅開啟功能,實際是否能開啟還取決於設備的寬度",
"download": "下載",
"edit": "編輯",
"editVirtKeys": "編輯虛擬按鍵",
"editor": "編輯器",
"editorHighlightTip": "目前的代碼高亮性能較為糟糕,可以選擇關閉以改善。",
"encode": "編碼",
"envVars": "環境變量",
"error": "錯誤",
"exampleName": "名稱範例",
"experimentalFeature": "實驗性功能",
"export": "匯出",
"extraArgs": "額外參數",
"failed": "失敗",
"fallbackSshDest": "備選 SSH 目標",
"fdroidReleaseTip": "如果你是從 F-Droid 下載的本應用,推薦關閉此選項",
"feedback": "反饋",
"feedbackOnGithub": "如果你有任何問題,請在 GitHub 反饋",
"fieldMustNotEmpty": "這些輸入框不能為空。",
"fileNotExist": "{file} 不存在",
"fileTooLarge": "文件 '{file}' 過大 '{size}',超過了 {sizeMax}",
"files": "文件",
"finished": "已完成",
"followSystem": "跟隨系統",
"font": "字型",
"fontSize": "字型大小",
"forExample": "例如",
"force": "強制",
"foundNUpdate": "找到 {count} 個更新",
"fullScreen": "全螢幕模式",
"fullScreenJitter": "全螢幕模式抖動",
"fullScreenJitterHelp": "防止燒屏",
"fullScreenTip": "當設備旋轉為橫屏時,是否開啟全熒幕模式?此選項僅適用於伺服器選項卡。",
"getPushTokenFailed": "未能獲取到推送 token",
"gettingToken": "正在獲取 Token...",
"goBackQ": "返回?",
"goto": "前往",
"hideTitleBar": "隱藏標題欄",
@@ -126,40 +72,26 @@
"highlight": "代碼高亮",
"homeWidgetUrlConfig": "桌面部件鏈接配置",
"host": "主機",
"hour": "小時",
"httpFailedWithCode": "請求失敗, 狀態碼: {code}",
"icloudSynced": "iCloud 已同步,某些設置可能需要重啟才能生效。",
"ignoreCert": "忽略證書",
"image": "鏡像",
"imagesList": "鏡像列表",
"import": "導入",
"inAppUpdate": "在 App 內更新?否則使用瀏覽器下載。",
"init": "初始化",
"inner": "內建",
"inputDomainHere": "在這裡輸入域名",
"install": "安裝",
"installDockerWithUrl": "請先 https://docs.docker.com/engine/install docker",
"invalid": "無效",
"invalidJson": "無效的 JSON",
"invalidVersion": "不支持的版本",
"invalidVersionHelp": "請確保正確安裝了 docker或者使用的非自編譯版本。如果沒有以上問題請在 {url} 提交問題。",
"isBusy": "當前正忙",
"jumpServer": "跳板伺服器",
"keepForeground": "請保持應用處於前台!",
"keepStatusWhenErr": "保留上次的伺服器狀態",
"keepStatusWhenErrTip": "僅在執行腳本出錯時",
"keyAuth": "密鑰認證",
"language": "語言",
"languageName": "繁體中文",
"lastTry": "最後嘗試",
"launchPage": "啓動頁",
"letterCache": "输入法字符緩存",
"letterCacheTip": "建議關閉,但關閉後將無法輸入 CJK 等文字。",
"license": "開源許可證",
"light": "亮",
"loadingFiles": "正在加載目錄...",
"license": "證",
"location": "位置",
"log": "日誌",
"loss": "丟包率",
"madeWithLove": "用❤️製作 by {myGithub}",
"manual": "手動",
@@ -167,37 +99,23 @@
"maxRetryCount": "伺服器嘗試重連次數",
"maxRetryCountEqual0": "會無限重試",
"min": "最小",
"minute": "分鐘",
"mission": "任務",
"more": "更多",
"moveOutServerFuncBtnsHelp": "開啟:可以在伺服器 Tab 頁的每個卡片下方顯示。關閉:在伺服器詳情頁頂部顯示。",
"ms": "毫秒",
"name": "名稱",
"needHomeDir": "如果你是群暉用戶,[看這裡](https://kb.synology.com/DSM/tutorial/user_enable_home_service)。其他系統用戶需搜索如何創建家目錄home directory。",
"needRestart": "需要重啓 App",
"net": "網路",
"netViewType": "網路視圖類型",
"newContainer": "新建容器",
"noClient": "沒有 SSH 連接",
"noInterface": "沒有可用的介面",
"noLineChart": "不使用折線圖",
"noLineChartForCpu": "CPU 不使用折線圖",
"noNotiPerm": "無通知權限,可能在下載應用程式更新時沒有進度提示。",
"noOptions": "無可選項",
"noPrivateKeyTip": "私鑰不存在,可能已被刪除/配置錯誤。",
"noPromptAgain": "不再提示",
"noResult": "無結果",
"noSavedPrivateKey": "沒有已保存的私鑰。",
"noSavedSnippet": "沒有已保存的程式片段。",
"noServerAvailable": "沒有可用的伺服器。",
"noTask": "沒有任務",
"noUpdateAvailable": "沒有可用更新",
"node": "節點",
"notAvailable": "不可用",
"notSelected": "未選擇",
"note": "備註",
"nullToken": "無 Token",
"ok": "好",
"onServerDetailPage": "在伺服器詳情頁",
"onlyOneLine": "僅顯示為一行(可滾動)",
"onlyWhenCoreBiggerThan8": "僅當核心數大於 8 時生效",
@@ -209,7 +127,6 @@
"path": "路徑",
"percentOfSize": "{size} 的 {percent}%",
"permission": "權限",
"pickFile": "選擇檔案",
"pingAvg": "平均:",
"pingInputIP": "請輸入目標 IP 或域名",
"pingNoServer": "沒有伺服器可用於 Ping\n請在伺服器 Tab 新增伺服器後再試",
@@ -217,8 +134,6 @@
"pkgUpgradeTip": "請在更新前備份系統。",
"platformNotSupportUpdate": "當前平台不支持更新,請編譯最新原始碼後手動安裝",
"plugInType": "插入類型",
"plzEnterHost": "請輸入主機",
"plzSelectKey": "請選擇私鑰",
"port": "埠",
"preview": "預覽",
"primaryColorSeed": "主要色調種子",
@@ -231,16 +146,11 @@
"pwd": "密碼",
"read": "读",
"reboot": "重启",
"rememberChoice": "記住選擇",
"rememberPwdInMem": "在記憶體中記住密碼",
"rememberPwdInMemTip": "用於容器、暫停等",
"rememberWindowSize": "記住窗口大小",
"remotePath": "遠端路徑",
"rename": "重命名",
"reportBugsOnGithubIssue": "請到 {url} 提交問題",
"restart": "重啓",
"restore": "恢復",
"restoreSuccess": "恢復成功,需要重啓 App 來應用更改",
"result": "結果",
"rotateAngel": "旋轉角度",
"route": "路由",
@@ -255,12 +165,6 @@
"serverDetailOrder": "詳情頁部件順序",
"serverFuncBtns": "伺服器功能按鈕",
"serverOrder": "伺服器順序",
"serverTabConnecting": "連接中...",
"serverTabEmpty": "現在沒有伺服器。\n點擊右下方按鈕來新增。",
"serverTabFailed": "失敗",
"serverTabLoading": "加載中...",
"serverTabPlzSave": "請再次保存該私鑰",
"serverTabUnkown": "未知狀態",
"setting": "設置",
"sftpDlPrepare": "準備連接至伺服器...",
"sftpEditorTip": "如果為空, 使用App內置的文件編輯器。如果有值, 則使用遠程伺服器的編輯器, 例如 `vim`(建議根據 `EDITOR` 自動獲取)。",
@@ -307,7 +211,6 @@
"trySudo": "嘗試使用 sudo",
"ttl": "TTL",
"unknown": "未知",
"unknownError": "未知錯誤",
"unkownConvertMode": "未知轉換模式",
"update": "更新",
"updateAll": "更新全部",
@@ -318,13 +221,11 @@
"upload": "上傳",
"upsideDown": "上下交換",
"uptime": "啟動時長",
"urlOrJson": "鏈接或 JSON",
"useCdn": "使用 CDN",
"useCdnTip": "非中國大陸用戶建議使用 CDN是否使用",
"useNoPwd": "将使用無密碼",
"usePodmanByDefault": "默認使用 Podman",
"used": "已用",
"user": "使用者",
"versionHaveUpdate": "找到新版本v1.0.{build}, 點擊更新",
"versionUnknownUpdate": "當前v1.0.{build},點擊檢查更新",
"versionUpdated": "當前v1.0.{build}, 已是最新版本",
@@ -338,7 +239,6 @@
"watchNotPaired": "沒有已配對的 Apple Watch",
"webdavSettingEmpty": "WebDav 設置項爲空",
"whenOpenApp": "當打開 App 時",
"willTakEeffectImmediately": "更改將會立即生效",
"wolTip": "在配置 WOL網絡喚醒每次連接伺服器都會先發送一次 WOL 請求。",
"write": "写",
"writeScriptFailTip": "寫入腳本失敗,可能是沒有權限/目錄不存在等。",

View File

@@ -81,6 +81,7 @@ Future<void> _initApp() async {
Future<void> _initData() async {
await Hive.initFlutter();
// Ordered by typeId
Hive.registerAdapter(PrivateKeyInfoAdapter()); // 1
Hive.registerAdapter(SnippetAdapter()); // 2

View File

@@ -9,8 +9,11 @@ import 'package:server_box/core/utils/sync/icloud.dart';
import 'package:server_box/core/utils/sync/webdav.dart';
import 'package:server_box/data/model/app/backup.dart';
import 'package:server_box/data/model/server/server_private_info.dart';
import 'package:server_box/data/model/server/snippet.dart';
import 'package:server_box/data/res/misc.dart';
import 'package:server_box/data/res/provider.dart';
import 'package:server_box/data/res/store.dart';
import 'package:icons_plus/icons_plus.dart';
class BackupPage extends StatelessWidget {
BackupPage({super.key});
@@ -21,23 +24,23 @@ class BackupPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: Text(l10n.backup, style: UIs.text18),
),
appBar: CustomAppBar(title: Text(libL10n.backup)),
body: _buildBody(context),
);
}
Widget _buildBody(BuildContext context) {
return ListView(
padding: const EdgeInsets.all(17),
padding: const EdgeInsets.all(13),
children: [
_buildTip(),
if (isMacOS || isIOS) _buildIcloud(context),
_buildWebdav(context),
_buildFile(context),
_buildClipboard(context),
CenterGreyTitle(libL10n.import),
_buildBulkImportServers(context),
_buildImportSnippet(context),
],
);
}
@@ -46,7 +49,7 @@ class BackupPage extends StatelessWidget {
return CardX(
child: ListTile(
leading: const Icon(Icons.warning),
title: Text(l10n.attention),
title: Text(libL10n.attention),
subtitle: Text(l10n.backupTip, style: UIs.textGrey),
),
);
@@ -56,11 +59,11 @@ class BackupPage extends StatelessWidget {
return CardX(
child: ExpandTile(
leading: const Icon(Icons.file_open),
title: Text(l10n.files),
title: Text(libL10n.file),
initiallyExpanded: true,
children: [
ListTile(
title: Text(l10n.backup),
title: Text(libL10n.backup),
trailing: const Icon(Icons.save),
onTap: () async {
final path = await Backup.backup();
@@ -69,7 +72,7 @@ class BackupPage extends StatelessWidget {
),
ListTile(
trailing: const Icon(Icons.restore),
title: Text(l10n.restore),
title: Text(libL10n.restore),
onTap: () async => _onTapFileRestore(context),
),
],
@@ -156,12 +159,12 @@ class BackupPage extends StatelessWidget {
children: [
TextButton(
onPressed: () async => _onTapWebdavDl(context),
child: Text(l10n.restore),
child: Text(libL10n.restore),
),
UIs.width7,
TextButton(
onPressed: () async => _onTapWebdavUp(context),
child: Text(l10n.backup),
child: Text(libL10n.backup),
),
],
);
@@ -177,10 +180,10 @@ class BackupPage extends StatelessWidget {
return CardX(
child: ExpandTile(
leading: const Icon(Icons.content_paste),
title: Text(l10n.clipboard),
title: Text(libL10n.clipboard),
children: [
ListTile(
title: Text(l10n.backup),
title: Text(libL10n.backup),
trailing: const Icon(Icons.save),
onTap: () async {
final path = await Backup.backup();
@@ -190,7 +193,7 @@ class BackupPage extends StatelessWidget {
),
ListTile(
trailing: const Icon(Icons.restore),
title: Text(l10n.restore),
title: Text(libL10n.restore),
onTap: () async => _onTapClipboardRestore(context),
),
],
@@ -201,14 +204,75 @@ class BackupPage extends StatelessWidget {
Widget _buildBulkImportServers(BuildContext context) {
return CardX(
child: ListTile(
title: Text(l10n.bulkImportServers),
leading: const Icon(Icons.import_export),
title: Text(l10n.server),
leading: const Icon(BoxIcons.bx_server),
onTap: () => _onBulkImportServers(context),
trailing: const Icon(Icons.keyboard_arrow_right),
),
);
}
Widget _buildImportSnippet(BuildContext context) {
return ListTile(
title: Text(l10n.snippet),
leading: const Icon(MingCute.code_line),
trailing: const Icon(Icons.keyboard_arrow_right),
onTap: () async {
final data = await context.showImportDialog(
title: l10n.snippet,
modelDef: Snippet.example.toJson(),
);
if (data == null) return;
final str = String.fromCharCodes(data);
final (list, _) = await context.showLoadingDialog(
fn: () => Computer.shared.start((s) {
return json.decode(s) as List;
}, str),
);
if (list == null || list.isEmpty) return;
final snippets = <Snippet>[];
final errs = <String>[];
for (final item in list) {
try {
final snippet = Snippet.fromJson(item);
snippets.add(snippet);
} catch (e) {
errs.add(e.toString());
}
}
if (snippets.isEmpty) {
context.showSnackBar(libL10n.empty);
return;
}
if (errs.isNotEmpty) {
context.showRoundDialog(
title: libL10n.error,
child: SingleChildScrollView(child: Text(errs.join('\n'))),
);
return;
}
final snippetNames = snippets.map((e) => e.name).join(', ');
context.showRoundDialog(
title: libL10n.attention,
child: SingleChildScrollView(
child: Text(
libL10n.askContinue('${libL10n.import} [$snippetNames]'),
),
),
actions: Btn.ok(
onTap: (c) {
for (final snippet in snippets) {
Pros.snippet.add(snippet);
}
c.pop();
context.pop();
},
).toList,
);
},
).cardx;
}
Future<void> _onTapFileRestore(BuildContext context) async {
final text = await Pfs.pickFileString();
if (text == null) return;
@@ -224,27 +288,20 @@ class BackupPage extends StatelessWidget {
}
await context.showRoundDialog(
title: l10n.restore,
child: Text(l10n.askContinue(
'${l10n.restore} ${l10n.backup}(${backup.date})',
title: libL10n.restore,
child: Text(libL10n.askContinue(
'${libL10n.restore} ${libL10n.backup}(${backup.date})',
)),
actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(l10n.cancel),
),
TextButton(
onPressed: () async {
actions: Btn.ok(
onTap: (c) async {
await backup.restore(force: true);
context.pop();
},
child: Text(l10n.ok),
),
],
).toList,
);
} catch (e, s) {
Loggers.app.warning('Import backup failed', e, s);
context.showErrDialog(e: e, s: s, operation: l10n.restore);
context.showErrDialog(e: e, s: s, operation: libL10n.restore);
}
}
@@ -255,7 +312,7 @@ class BackupPage extends StatelessWidget {
if (files.isEmpty) return context.showSnackBar(l10n.dirEmpty);
final fileName = await context.showPickSingleDialog(
title: l10n.restore,
title: libL10n.restore,
items: files,
);
if (fileName == null) return;
@@ -268,7 +325,7 @@ class BackupPage extends StatelessWidget {
final dlBak = await Computer.shared.start(Backup.fromJsonString, dlFile);
await dlBak.restore(force: true);
} catch (e, s) {
context.showErrDialog(e: e, s: s, operation: l10n.restore);
context.showErrDialog(e: e, s: s, operation: libL10n.restore);
Loggers.app.warning('Download webdav backup failed', e, s);
} finally {
webdavLoading.value = false;
@@ -313,7 +370,7 @@ class BackupPage extends StatelessWidget {
onSubmitted: (p0) => FocusScope.of(context).requestFocus(nodeUser),
),
Input(
label: l10n.user,
label: libL10n.user,
controller: user,
node: nodeUser,
suggestion: false,
@@ -328,14 +385,7 @@ class BackupPage extends StatelessWidget {
),
],
),
actions: [
TextButton(
onPressed: () {
context.pop(true);
},
child: Text(l10n.ok),
),
],
actions: Btn.ok(onTap: (c) => context.pop(true)).toList,
);
if (result == true) {
final result = await Webdav.test(url.text, user.text, pwd.text);
@@ -351,7 +401,7 @@ class BackupPage extends StatelessWidget {
void _onTapClipboardRestore(BuildContext context) async {
final text = await Pfs.paste();
if (text == null || text.isEmpty) {
context.showSnackBar(l10n.fieldMustNotEmpty);
context.showSnackBar(libL10n.empty);
return;
}
@@ -367,27 +417,20 @@ class BackupPage extends StatelessWidget {
}
await context.showRoundDialog(
title: l10n.restore,
child: Text(l10n.askContinue(
'${l10n.restore} ${l10n.backup}(${backup.date})',
title: libL10n.restore,
child: Text(libL10n.askContinue(
'${libL10n.restore} ${libL10n.backup}(${backup.date})',
)),
actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(l10n.cancel),
),
TextButton(
onPressed: () async {
actions: Btn.ok(
onTap: (c) async {
await backup.restore(force: true);
context.pop();
},
child: Text(l10n.ok),
),
],
).toList,
);
} catch (e, s) {
Loggers.app.warning('Import backup failed', e, s);
context.showErrDialog(e: e, s: s, operation: l10n.restore);
context.showErrDialog(e: e, s: s, operation: libL10n.restore);
}
}
@@ -408,14 +451,9 @@ class BackupPage extends StatelessWidget {
);
if (err != null || spis == null) return;
final sure = await context.showRoundDialog<bool>(
title: l10n.import,
child: Text(l10n.askContinue('${spis.length} ${l10n.server}')),
actions: [
TextButton(
onPressed: () => context.pop(true),
child: Text(l10n.ok),
),
],
title: libL10n.import,
child: Text(libL10n.askContinue('${spis.length} ${l10n.server}')),
actions: Btn.ok(onTap: (c) => context.pop(true)).toList,
);
if (sure == true) {
final (suc, err) = await context.showLoadingDialog(
@@ -430,7 +468,7 @@ class BackupPage extends StatelessWidget {
context.showSnackBar(l10n.success);
}
} catch (e, s) {
context.showErrDialog(e: e, s: s, operation: l10n.import);
context.showErrDialog(e: e, s: s, operation: libL10n.import);
Loggers.app.warning('Import servers failed', e, s);
}
}

View File

@@ -98,7 +98,7 @@ class _ContainerPageState extends State<ContainerPage> {
UIs.height13,
Padding(
padding: const EdgeInsets.symmetric(horizontal: 23),
child: Text(_container.error?.toString() ?? l10n.unknownError),
child: Text(_container.error.toString()),
),
const Spacer(),
_buildEditHost(),
@@ -285,16 +285,13 @@ class _ContainerPageState extends State<ContainerPage> {
if (emptyPs && emptyImgs) {
children.add(Padding(
padding: const EdgeInsets.fromLTRB(17, 17, 17, 0),
child: Text(
l10n.dockerEmptyRunningItems,
textAlign: TextAlign.center,
),
child: SimpleMarkdown(data: l10n.dockerEmptyRunningItems),
));
}
children.add(
TextButton(
onPressed: _showEditHostDialog,
child: Text(l10n.dockerEditHost),
child: Text('${libL10n.edit} DOCKER_HOST'),
),
);
return CardX(
@@ -343,7 +340,7 @@ class _ContainerPageState extends State<ContainerPage> {
Input(
type: TextInputType.text,
controller: nameCtrl,
label: l10n.containerName,
label: libL10n.name,
hint: 'xxx',
suggestion: false,
),
@@ -356,13 +353,7 @@ class _ContainerPageState extends State<ContainerPage> {
),
],
),
actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(l10n.cancel),
),
TextButton(
onPressed: () async {
actions: Btn.ok(onTap: (c) async {
context.pop();
await _showAddCmdPreview(
_buildAddCmd(
@@ -371,11 +362,7 @@ class _ContainerPageState extends State<ContainerPage> {
argsCtrl.text.trim(),
),
);
},
child: Text(l10n.ok),
)
],
);
}).toList);
}
Future<void> _showAddCmdPreview(String cmd) async {
@@ -385,7 +372,7 @@ class _ContainerPageState extends State<ContainerPage> {
actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(l10n.cancel),
child: Text(libL10n.cancel),
),
TextButton(
onPressed: () async {
@@ -397,8 +384,8 @@ class _ContainerPageState extends State<ContainerPage> {
if (err != null || result != null) {
final e = result?.message ?? err?.toString();
context.showRoundDialog(
title: l10n.error,
child: Text(e ?? l10n.unknownError),
title: libL10n.error,
child: Text(e.toString()),
);
}
},
@@ -426,7 +413,7 @@ class _ContainerPageState extends State<ContainerPage> {
final host = Stores.container.fetch(id);
final ctrl = TextEditingController(text: host);
await context.showRoundDialog(
title: l10n.dockerEditHost,
title: 'DOCKER_HOST',
child: Input(
maxLines: 2,
controller: ctrl,
@@ -434,12 +421,7 @@ class _ContainerPageState extends State<ContainerPage> {
hint: 'unix:///run/user/1000/docker.sock',
suggestion: false,
),
actions: [
TextButton(
onPressed: () => _onSaveDockerHost(ctrl.text),
child: Text(l10n.ok),
),
],
actions: Btn.ok(onTap: (c) => _onSaveDockerHost(ctrl.text)).toList,
);
}
@@ -451,24 +433,20 @@ class _ContainerPageState extends State<ContainerPage> {
void _showImageRmDialog(ContainerImg e) {
context.showRoundDialog(
title: l10n.attention,
child: Text(l10n.askContinue('${l10n.delete} Image(${e.repository})')),
actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(l10n.cancel),
title: libL10n.attention,
child: Text(
libL10n.askContinue('${libL10n.delete} Image(${e.repository})'),
),
TextButton(
onPressed: () async {
actions: Btn.ok(
onTap: (c) async {
context.pop();
final result = await _container.run('rmi ${e.id} -f');
if (result != null) {
context.showSnackBar(result.message ?? l10n.unknownError);
context.showSnackBar(result.message ?? 'null');
}
},
child: Text(l10n.ok, style: UIs.textRed),
),
],
red: true,
).toList,
);
}
@@ -482,12 +460,12 @@ class _ContainerPageState extends State<ContainerPage> {
case ContainerMenu.rm:
var force = false;
context.showRoundDialog(
title: l10n.attention,
title: libL10n.attention,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(l10n.askContinue(
'${l10n.delete} Container(${dItem.name})',
Text(libL10n.askContinue(
'${libL10n.delete} Container(${dItem.name})',
)),
UIs.height13,
Row(
@@ -505,9 +483,7 @@ class _ContainerPageState extends State<ContainerPage> {
)
],
),
actions: [
TextButton(
onPressed: () async {
actions: Btn.ok(onTap: (c) async {
context.pop();
final (result, err) = await context.showLoadingDialog(
@@ -516,14 +492,11 @@ class _ContainerPageState extends State<ContainerPage> {
if (err != null || result != null) {
final e = result?.message ?? err?.toString();
context.showRoundDialog(
title: l10n.error,
child: Text(e ?? l10n.unknownError),
title: libL10n.error,
child: Text(e ?? 'null'),
);
}
},
child: Text(l10n.ok),
)
],
}).toList,
);
break;
case ContainerMenu.start:
@@ -533,8 +506,8 @@ class _ContainerPageState extends State<ContainerPage> {
if (err != null || result != null) {
final e = result?.message ?? err?.toString();
context.showRoundDialog(
title: l10n.error,
child: Text(e ?? l10n.unknownError),
title: libL10n.error,
child: Text(e ?? 'null'),
);
}
break;
@@ -545,8 +518,8 @@ class _ContainerPageState extends State<ContainerPage> {
if (err != null || result != null) {
final e = result?.message ?? err?.toString();
context.showRoundDialog(
title: l10n.error,
child: Text(e ?? l10n.unknownError),
title: libL10n.error,
child: Text(e ?? 'null'),
);
}
break;
@@ -557,8 +530,8 @@ class _ContainerPageState extends State<ContainerPage> {
if (err != null || result != null) {
final e = result?.message ?? err?.toString();
context.showRoundDialog(
title: l10n.error,
child: Text(e ?? l10n.unknownError),
title: libL10n.error,
child: Text(e ?? 'null'),
);
}
break;

View File

@@ -149,7 +149,7 @@ class _EditorPageState extends State<EditorPage> {
fn: () => File(widget.path!).writeAsString(_controller.text),
);
if (res == null) {
context.showSnackBar(l10n.failed);
context.showSnackBar(libL10n.fail);
return;
}
context.pop(true);

View File

@@ -128,7 +128,7 @@ class _HomePageState extends State<HomePage>
),
IconButton(
icon: const Icon(Icons.developer_mode, size: 21),
tooltip: l10n.debug,
tooltip: 'Debug',
onPressed: () => AppRoutes.debug().go(context),
),
],
@@ -245,17 +245,17 @@ class _HomePageState extends State<HomePage>
),
ListTile(
leading: const Icon(BoxIcons.bxs_file_blank),
title: Text(l10n.files),
title: Text(libL10n.file),
onTap: () => AppRoutes.localStorage().go(context),
),
ListTile(
leading: const Icon(MingCute.file_import_fill),
title: Text(l10n.backup),
title: Text(libL10n.backup),
onTap: () => AppRoutes.backup().go(context),
),
ListTile(
leading: const Icon(OctIcons.feed_discussion),
title: Text('${l10n.about} & ${l10n.feedback}'),
title: Text('${l10n.about} & ${libL10n.feedback}'),
onTap: _showAboutDialog,
)
].map((e) => CardX(child: e)).toList(),
@@ -274,7 +274,7 @@ class _HomePageState extends State<HomePage>
),
TextButton(
onPressed: () => Urls.appHelp.launch(),
child: Text(l10n.feedback),
child: Text(libL10n.feedback),
),
TextButton(
onPressed: () => showLicensePage(context: context),
@@ -391,7 +391,7 @@ ${GithubIds.participants.map((e) => '[$e](${e.url})').join(' ')}
}
} catch (e, trace) {
context.showRoundDialog(
title: l10n.error,
title: libL10n.error,
child: Text('${l10n.save}:\n$e'),
);
Loggers.app.warning('Update json settings failed', e, trace);

View File

@@ -3,7 +3,6 @@ import 'dart:async';
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:server_box/core/extension/context/locale.dart';
import 'package:server_box/data/model/server/server.dart';
import 'package:server_box/data/provider/server.dart';
import 'package:server_box/data/res/build_data.dart';
@@ -53,7 +52,7 @@ final class _WearHomeState extends State<WearHome> with AfterLayoutMixin {
children: [
IconButton(onPressed: () {}, icon: const Icon(Icons.add)),
UIs.height7,
Text(l10n.restore)
Text(libL10n.restore)
],
),
);

View File

@@ -33,7 +33,7 @@ class _IPerfPageState extends State<IPerfPage> {
child: const Icon(Icons.send),
onPressed: () {
if (_hostCtrl.text.isEmpty || _portCtrl.text.isEmpty) {
context.showSnackBar(l10n.fieldMustNotEmpty);
context.showSnackBar(libL10n.empty);
return;
}
AppRoutes.ssh(

View File

@@ -53,18 +53,16 @@ class _PingPageState extends State<PingPage>
heroTag: 'ping',
onPressed: () {
context.showRoundDialog(
title: l10n.choose,
title: libL10n.select,
child: Input(
autoFocus: true,
controller: _textEditingController,
hint: l10n.inputDomainHere,
maxLines: 1,
suggestion: false,
hint: 'example.com',
maxLines: 2,
minLines: 1,
onSubmitted: (_) => _doPing(),
),
actions: [
TextButton(onPressed: _doPing, child: Text(l10n.ok)),
],
actions: Btn.ok(onTap: (c) => _doPing()).toList,
);
},
child: const Icon(Icons.search),
@@ -77,12 +75,12 @@ class _PingPageState extends State<PingPage>
await doPing();
} catch (e) {
context.showRoundDialog(
title: l10n.error,
title: libL10n.error,
child: Text(e.toString()),
actions: [
TextButton(
onPressed: () => Pfs.copy(e.toString()),
child: Text(l10n.copy),
child: Text(libL10n.copy),
),
],
);
@@ -92,12 +90,7 @@ class _PingPageState extends State<PingPage>
Widget _buildBody() {
if (isInit) {
return Center(
child: Text(
l10n.noResult,
style: const TextStyle(fontSize: 15),
),
);
return Center(child: Text(libL10n.empty));
}
return ListView.builder(
padding: const EdgeInsets.all(11),
@@ -139,7 +132,7 @@ class _PingPageState extends State<PingPage>
String _buildPingSummary(PingResult result, String unknown, String ms) {
final ip = result.ip ?? unknown;
if (result.results == null || result.results!.isEmpty) {
return '$ip - ${l10n.noResult}';
return '$ip - ${libL10n.empty}';
}
final ttl = result.results?.firstOrNull?.ttl ?? unknown;
final loss = result.statistic?.loss ?? unknown;

View File

@@ -80,33 +80,28 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
CustomAppBar _buildAppBar() {
final actions = [
IconButton(
tooltip: l10n.delete,
tooltip: libL10n.delete,
onPressed: () {
context.showRoundDialog(
title: l10n.attention,
child: Text(l10n.askContinue(
'${l10n.delete} ${l10n.privateKey}(${widget.pki!.id})',
title: libL10n.attention,
child: Text(libL10n.askContinue(
'${libL10n.delete} ${l10n.privateKey}(${widget.pki!.id})',
)),
actions: [
TextButton(
onPressed: () {
actions: Btn.ok(
onTap: (c) {
Pros.key.delete(widget.pki!);
context.pop();
context.pop();
},
child: Text(
l10n.ok,
style: UIs.textRed,
),
),
],
red: true,
).toList,
);
},
icon: const Icon(Icons.delete),
)
];
return CustomAppBar(
title: Text(l10n.edit, style: UIs.text18),
title: Text(libL10n.edit),
actions: widget.pki == null ? null : actions,
);
}
@@ -133,7 +128,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
type: TextInputType.text,
node: _nameNode,
onSubmitted: (_) => _focusScope.requestFocus(_keyNode),
label: l10n.name,
label: libL10n.name,
icon: Icons.info,
suggestion: true,
),
@@ -155,7 +150,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
final file = File(path);
if (!file.existsSync()) {
context.showSnackBar(l10n.fileNotExist(path));
context.showSnackBar(libL10n.notExistFmt(path));
return;
}
final size = (await file.stat()).size;
@@ -174,7 +169,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
// dartssh2 accepts only LF (but not CRLF or CR)
_keyController.text = _standardizeLineSeparators(content.trim());
},
child: Text(l10n.pickFile),
child: Text(libL10n.file),
),
Input(
controller: _pwdController,
@@ -200,7 +195,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
final key = _standardizeLineSeparators(_keyController.text.trim());
final pwd = _pwdController.text;
if (name.isEmpty || key.isEmpty) {
context.showSnackBar(l10n.fieldMustNotEmpty);
context.showSnackBar(libL10n.empty);
return;
}
FocusScope.of(context).unfocus();

View File

@@ -24,7 +24,7 @@ class _PrivateKeyListState extends State<PrivateKeysListPage>
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: Text(l10n.privateKey, style: UIs.text18),
title: Text(l10n.privateKey),
),
body: _buildBody(),
floatingActionButton: FloatingActionButton(
@@ -38,9 +38,7 @@ class _PrivateKeyListState extends State<PrivateKeysListPage>
return Consumer<PrivateKeyProvider>(
builder: (_, key, __) {
if (key.pkis.isEmpty) {
return Center(
child: Text(l10n.noSavedPrivateKey),
);
return Center(child: Text(libL10n.empty));
}
return ListView.builder(
padding: const EdgeInsets.all(13),
@@ -80,21 +78,12 @@ class _PrivateKeyListState extends State<PrivateKeysListPage>
key: idRsaFile.readAsStringSync(),
);
context.showRoundDialog(
title: l10n.attention,
title: libL10n.attention,
child: Text(l10n.addSystemPrivateKeyTip),
actions: [
TextButton(
onPressed: () {
actions: Btn.ok(onTap: (c) {
context.pop();
AppRoutes.keyEdit(pki: sysPk).go(context);
},
child: Text(l10n.ok),
),
TextButton(
onPressed: () => Navigator.pop(context),
child: Text(l10n.cancel),
),
],
}).toList,
);
}
}

View File

@@ -51,9 +51,10 @@ class _ProcessPageState extends State<ProcessPage> {
Future<void> _refresh() async {
if (mounted) {
final result = await _client?.run(ShellFunc.process.exec).string;
final result =
await _client?.run(ShellFunc.process.exec(widget.spi.id)).string;
if (result == null || result.isEmpty) {
context.showSnackBar(l10n.noResult);
context.showSnackBar(libL10n.empty);
return;
}
_result = PsResult.parse(result, sort: _procSortMode);
@@ -100,12 +101,12 @@ class _ProcessPageState extends State<ProcessPage> {
actions.add(IconButton(
icon: const Icon(Icons.error),
onPressed: () => context.showRoundDialog(
title: l10n.error,
title: libL10n.error,
child: SingleChildScrollView(child: Text(_result.error!)),
actions: [
TextButton(
onPressed: () => Pfs.copy(_result.error!),
child: Text(l10n.copy),
child: Text(libL10n.copy),
),
],
),
@@ -153,20 +154,15 @@ class _ProcessPageState extends State<ProcessPage> {
onTap: () => _lastFocusId = proc.pid,
onLongPress: () {
context.showRoundDialog(
title: l10n.attention,
child: Text(l10n.askContinue(
title: libL10n.attention,
child: Text(libL10n.askContinue(
'${l10n.stop} ${l10n.process}(${proc.pid})',
)),
actions: [
TextButton(
onPressed: () async {
actions: Btn.ok(onTap: (c) async {
await _client?.run('kill ${proc.pid}');
await _refresh();
context.pop();
},
child: Text(l10n.ok),
),
],
}).toList,
);
},
selected: _lastFocusId == proc.pid,

View File

@@ -378,7 +378,7 @@ final class _PvePageState extends State<PvePage> {
],
),
UIs.height7,
KvRow(k: l10n.content, v: item.content),
KvRow(k: libL10n.content, v: item.content),
KvRow(k: l10n.plugInType, v: item.plugintype),
],
),
@@ -419,14 +419,12 @@ final class _PvePageState extends State<PvePage> {
void _onCtrl(PveCtrlFunc func, String action, PveCtrlIface item) async {
final sure = await context.showRoundDialog<bool>(
title: l10n.attention,
child: Text(l10n.askContinue('$action ${item.id}')),
actions: [
TextButton(
onPressed: () => context.pop(true),
child: Text(l10n.ok, style: UIs.textRed),
),
],
title: libL10n.attention,
child: Text(libL10n.askContinue('$action ${item.id}')),
actions: Btn.ok(
onTap: (c) => context.pop(true),
red: true,
).toList,
);
if (sure != true) return;
@@ -436,7 +434,7 @@ final class _PvePageState extends State<PvePage> {
if (suc == true) {
context.showSnackBar(l10n.success);
} else {
context.showSnackBar(err?.toString() ?? l10n.failed);
context.showSnackBar(err?.toString() ?? libL10n.fail);
}
}

View File

@@ -83,9 +83,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
if (s == null) {
return Scaffold(
appBar: const CustomAppBar(),
body: Center(
child: Text(l10n.noClient),
),
body: Center(child: Text(libL10n.empty)),
);
}
return _buildMainPage(s);
@@ -123,7 +121,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
CustomAppBar _buildAppBar(Server si) {
return CustomAppBar(
title: Text(si.spi.name, style: UIs.text18),
title: Text(si.spi.name),
actions: [
IconButton(
icon: const Icon(Icons.edit),
@@ -484,7 +482,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(l10n.close),
child: Text(libL10n.close),
)
],
);
@@ -528,7 +526,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(l10n.close),
child: Text(libL10n.close),
)
],
);
@@ -605,18 +603,10 @@ class _ServerDetailPageState extends State<ServerDetailPage>
Widget _buildNetView(ServerStatus ss) {
final ns = ss.netSpeed;
final children = <Widget>[];
if (ns.devices.isEmpty) {
children.add(Center(
child: Text(
l10n.noInterface,
style: UIs.text13Grey,
),
));
} else {
final devices = ns.devices;
devices.sort(_netSortType.value.getSortFunc(ns));
children.addAll(devices.map((e) => _buildNetSpeedItem(ns, e)));
}
return CardX(
child: ExpandTile(
leading: Icon(ServerDetailCards.net.icon, size: 17),
@@ -870,7 +860,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(l10n.close),
child: Text(libL10n.close),
),
],
);

View File

@@ -92,7 +92,7 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
PreferredSizeWidget _buildAppBar() {
return CustomAppBar(
title: Text(l10n.edit, style: UIs.text18),
title: Text(libL10n.edit),
actions: widget.spi != null ? [_buildDelBtn()] : null,
);
}
@@ -101,22 +101,20 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
return IconButton(
onPressed: () {
context.showRoundDialog(
title: l10n.attention,
title: libL10n.attention,
child: StatefulBuilder(builder: (ctx, setState) {
return Text(l10n.askContinue(
'${l10n.delete} ${l10n.server}(${widget.spi!.name})',
return Text(libL10n.askContinue(
'${libL10n.delete} ${l10n.server}(${widget.spi!.name})',
));
}),
actions: [
TextButton(
onPressed: () async {
actions: Btn.ok(
onTap: (c) async {
context.pop();
Pros.server.delServer(widget.spi!.id);
context.pop(true);
},
child: Text(l10n.ok, style: UIs.textRed),
),
],
red: true,
).toList,
);
},
icon: const Icon(Icons.delete),
@@ -132,8 +130,8 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
type: TextInputType.text,
node: _nameFocus,
onSubmitted: (_) => _focusScope.requestFocus(_ipFocus),
hint: l10n.exampleName,
label: l10n.name,
hint: libL10n.example,
label: libL10n.name,
icon: BoxIcons.bx_rename,
obscureText: false,
autoCorrect: true,
@@ -164,7 +162,7 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
type: TextInputType.text,
node: _usernameFocus,
onSubmitted: (_) => _focusScope.requestFocus(_alterUrlFocus),
label: l10n.user,
label: libL10n.user,
icon: Icons.account_box,
hint: 'root',
suggestion: false,
@@ -266,7 +264,7 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
});
tiles.add(
ListTile(
title: Text(l10n.addPrivateKey),
title: Text(libL10n.add),
contentPadding: padding,
trailing: const Padding(
padding: EdgeInsets.only(right: 13),
@@ -331,7 +329,7 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
Input(
controller: _preferTempDevCtrl,
type: TextInputType.text,
label: l10n.deviceName,
label: libL10n.device,
icon: MingCute.low_temperature_line,
hint: 'nvme-pci-0400',
suggestion: false,
@@ -421,7 +419,7 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
).cardx,
ListTile(
leading: const Icon(MingCute.doc_line),
title: Text(l10n.doc),
title: Text(libL10n.doc),
trailing: const Icon(Icons.open_in_new, size: 17),
onTap: () => l10n.customCmdDocUrl.launch(),
).cardx,
@@ -494,7 +492,7 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
)
.toList();
children.add(ListTile(
title: Text(l10n.clear),
title: Text(libL10n.clear),
trailing: const Icon(Icons.clear),
onTap: () => _jumpServer.value = null,
contentPadding: const EdgeInsets.symmetric(horizontal: 17),
@@ -513,31 +511,31 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
void _onSave() async {
if (_ipController.text.isEmpty) {
context.showSnackBar(l10n.plzEnterHost);
context.showSnackBar('${libL10n.empty} ${l10n.host}');
return;
}
if (_keyIdx.value == null && _passwordController.text.isEmpty) {
final cancel = await context.showRoundDialog<bool>(
title: l10n.attention,
child: Text(l10n.askContinue(l10n.useNoPwd)),
title: libL10n.attention,
child: Text(libL10n.askContinue(l10n.useNoPwd)),
actions: [
TextButton(
onPressed: () => context.pop(false),
child: Text(l10n.ok),
child: Text(libL10n.ok),
),
TextButton(
onPressed: () => context.pop(true),
child: Text(l10n.cancel),
child: Text(libL10n.cancel),
)
],
);
if (cancel != false) {
return;
}
if (cancel != false) return;
}
// If [_pubKeyIndex] is -1, it means that the user has not selected
if (_keyIdx.value == -1) {
context.showSnackBar(l10n.plzSelectKey);
context.showSnackBar(libL10n.empty);
return;
}
if (_usernameController.text.isEmpty) {
@@ -568,7 +566,7 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
if (wol != null) {
final wolValidation = wol.validate();
if (!wolValidation.$2) {
context.showSnackBar('${l10n.failed}: ${wolValidation.$1}');
context.showSnackBar('${libL10n.fail}: ${wolValidation.$1}');
return;
}
}
@@ -608,7 +606,7 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
borderRadius: BorderRadius.circular(10),
onTap: () {
context.showRoundDialog(
title: l10n.attention,
title: libL10n.attention,
child: SimpleMarkdown(data: l10n.writeScriptTip),
actions: [Btn.ok()],
);
@@ -618,7 +616,7 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
children: [
const Icon(Icons.tips_and_updates, size: 15, color: Colors.grey),
UIs.width13,
Text(l10n.attention, style: UIs.textGrey)
Text(libL10n.attention, style: UIs.textGrey)
],
).paddingSymmetric(horizontal: 13, vertical: 3),
),

View File

@@ -106,7 +106,7 @@ class _ServerPageState extends State<ServerPage>
child: FloatingActionButton(
heroTag: 'addServer',
onPressed: () => AppRoutes.serverEdit().go(context),
tooltip: l10n.addAServer,
tooltip: libL10n.add,
child: const Icon(Icons.add),
),
),
@@ -141,10 +141,7 @@ class _ServerPageState extends State<ServerPage>
return Consumer<ServerProvider>(builder: (_, pro, __) {
if (pro.serverOrder.isEmpty) {
return Center(
child: Text(
l10n.serverTabEmpty,
textAlign: TextAlign.center,
),
child: Text(libL10n.empty, textAlign: TextAlign.center),
);
}
@@ -190,10 +187,7 @@ class _ServerPageState extends State<ServerPage>
}
if (pro.serverOrder.isEmpty) {
return Center(
child: Text(
l10n.serverTabEmpty,
textAlign: TextAlign.center,
),
child: Text(libL10n.empty, textAlign: TextAlign.center),
);
}
@@ -348,19 +342,20 @@ class _ServerPageState extends State<ServerPage>
}
List<Widget> _buildFlippedCard(Server srv) {
const textStyle = TextStyle(color: Colors.grey);
final children = [
Btn.column(
onTap: (_) => _askFor(
func: () async {
if (Stores.setting.showSuspendTip.fetch()) {
await context.showRoundDialog(
title: l10n.attention,
title: libL10n.attention,
child: Text(l10n.suspendTip),
);
Stores.setting.showSuspendTip.put(false);
}
srv.client?.execWithPwd(
ShellFunc.suspend.exec,
ShellFunc.suspend.exec(srv.spi.id),
context: context,
id: srv.id,
);
@@ -368,39 +363,43 @@ class _ServerPageState extends State<ServerPage>
typ: l10n.suspend,
name: srv.spi.name,
),
icon: const Icon(Icons.stop),
icon: const Icon(Icons.stop, color: Colors.grey),
text: l10n.suspend,
textStyle: textStyle,
),
Btn.column(
onTap: (_) => _askFor(
func: () => srv.client?.execWithPwd(
ShellFunc.shutdown.exec,
ShellFunc.shutdown.exec(srv.spi.id),
context: context,
id: srv.id,
),
typ: l10n.shutdown,
name: srv.spi.name,
),
icon: const Icon(Icons.power_off),
icon: const Icon(Icons.power_off, color: Colors.grey),
text: l10n.shutdown,
textStyle: textStyle,
),
Btn.column(
onTap: (_) => _askFor(
func: () => srv.client?.execWithPwd(
ShellFunc.reboot.exec,
ShellFunc.reboot.exec(srv.spi.id),
context: context,
id: srv.id,
),
typ: l10n.reboot,
name: srv.spi.name,
),
icon: const Icon(Icons.restart_alt),
icon: const Icon(Icons.restart_alt, color: Colors.grey),
text: l10n.reboot,
textStyle: textStyle,
),
Btn.column(
onTap: (_) => AppRoutes.serverEdit(spi: srv.spi).go(context),
icon: const Icon(Icons.edit),
text: l10n.edit,
icon: const Icon(Icons.edit, color: Colors.grey),
text: libL10n.edit,
textStyle: textStyle,
)
];
@@ -445,7 +444,7 @@ class _ServerPageState extends State<ServerPage>
Widget _buildServerCardTitle(Server s) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 7),
padding: const EdgeInsets.only(left: 7, right: 13),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@@ -497,15 +496,15 @@ class _ServerPageState extends State<ServerPage>
),
ServerConn.disconnected => (
const Icon(
BoxIcons.bx_link,
size: 21,
MingCute.link_3_line,
size: 19,
color: Colors.grey,
),
() => Pros.server.refresh(spi: s.spi)
),
ServerConn.finished => (
const Icon(
BoxIcons.bx_unlink,
MingCute.unlink_2_line,
size: 17,
color: Colors.grey,
),
@@ -535,15 +534,14 @@ class _ServerPageState extends State<ServerPage>
Widget _buildTopRightText(Server s) {
final hasErr = s.conn == ServerConn.failed && s.status.err != null;
final str = s.getTopRightStr(s.spi);
if (str == null) return UIs.placeholder;
return GestureDetector(
onTap: () {
if (!hasErr) return;
_showFailReason(s.status);
},
child: Text(
s.getTopRightStr(s.spi),
style: UIs.text13Grey,
),
child: Text(str, style: UIs.text13Grey),
);
}
@@ -552,15 +550,15 @@ class _ServerPageState extends State<ServerPage>
${ss.err?.solution ?? l10n.unknown}
```sh
${ss.err?.message ?? l10n.unknownError}
${ss.err?.message ?? 'null'}
''';
context.showRoundDialog(
title: l10n.error,
title: libL10n.error,
child: SingleChildScrollView(child: SimpleMarkdown(data: md)),
actions: [
TextButton(
onPressed: () => Pfs.copy(md),
child: Text(l10n.copy),
child: Text(libL10n.copy),
)
],
);
@@ -692,17 +690,14 @@ ${ss.err?.message ?? l10n.unknownError}
required String name,
}) {
context.showRoundDialog(
title: l10n.attention,
child: Text(l10n.askContinue('$typ ${l10n.server}($name)')),
actions: [
TextButton(
onPressed: () {
title: libL10n.attention,
child: Text(libL10n.askContinue('$typ ${l10n.server}($name)')),
actions: Btn.ok(
onTap: (c) {
context.pop();
func();
},
child: Text(l10n.ok),
),
],
).toList,
);
}
@@ -750,3 +745,60 @@ class _CardStatus {
);
}
}
extension _ServerX on Server {
String? getTopRightStr(ServerPrivateInfo spi) {
switch (conn) {
case ServerConn.disconnected:
return null;
case ServerConn.finished:
// Highest priority of temperature display
final cmdTemp = () {
final val = status.customCmds['server_card_top_right'];
if (val == null) return null;
// This returned value is used on server card top right, so it should
// be a single line string.
return val.split('\n').lastOrNull;
}();
final temperatureVal = () {
// Second priority
final preferTempDev = spi.custom?.preferTempDev;
if (preferTempDev != null) {
final preferTemp = status.sensors
.firstWhereOrNull((e) => e.device == preferTempDev)
?.summary
?.split(' ')
.firstOrNull;
if (preferTemp != null) {
return double.tryParse(preferTemp.replaceFirst('°C', ''));
}
}
// Last priority
final temp = status.temps.first;
if (temp != null) {
return temp;
}
return null;
}();
final upTime = status.more[StatusCmdType.uptime];
final items = [
cmdTemp ??
(temperatureVal != null
? '${temperatureVal.toStringAsFixed(1)}°C'
: null),
upTime
];
final str = items.where((e) => e != null && e.isNotEmpty).join(' | ');
if (str.isEmpty) return libL10n.empty;
return str;
case ServerConn.loading:
return null;
case ServerConn.connected:
return null;
case ServerConn.connecting:
return null;
case ServerConn.failed:
return status.err != null ? l10n.viewErr : libL10n.fail;
}
}
}

View File

@@ -5,7 +5,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_highlight/theme_map.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:icons_plus/icons_plus.dart';
import 'package:locale_names/locale_names.dart';
import 'package:server_box/core/extension/context/locale.dart';
import 'package:server_box/data/res/rebuild.dart';
import 'package:server_box/data/res/store.dart';
@@ -37,24 +36,19 @@ class _SettingPageState extends State<SettingPage> {
IconButton(
icon: const Icon(Icons.delete),
onPressed: () => context.showRoundDialog(
title: l10n.attention,
title: libL10n.attention,
child: SimpleMarkdown(
data: l10n.askContinue(
'${l10n.delete} **${l10n.all}** ${l10n.setting}',
data: libL10n.askContinue(
'${libL10n.delete} **${libL10n.all}** ${l10n.setting}',
)),
actions: [
TextButton(
onPressed: () {
actions: Btn.ok(
onTap: (c) {
context.pop();
_setting.box.deleteAll(_setting.box.keys);
context.showSnackBar(l10n.success);
},
child: Text(
l10n.ok,
style: const TextStyle(color: Colors.red),
),
),
],
red: true,
).toList,
),
),
],
@@ -62,22 +56,22 @@ class _SettingPageState extends State<SettingPage> {
body: ListView(
padding: const EdgeInsets.symmetric(horizontal: 17),
children: [
_buildTitle('App'),
const CenterGreyTitle('App'),
_buildApp(),
_buildTitle(l10n.server),
CenterGreyTitle(l10n.server),
_buildServer(),
_buildTitle(l10n.container),
CenterGreyTitle(l10n.container),
_buildContainer(),
_buildTitle('SSH'),
const CenterGreyTitle('SSH'),
_buildSSH(),
_buildTitle('SFTP'),
const CenterGreyTitle('SFTP'),
_buildSFTP(),
_buildTitle(l10n.editor),
CenterGreyTitle(l10n.editor),
_buildEditor(),
/// Fullscreen Mode is designed for old mobile phone which can be
/// used as a status screen.
if (isMobile) _buildTitle(l10n.fullScreen),
if (isMobile) CenterGreyTitle(l10n.fullScreen),
if (isMobile) _buildFullScreen(),
const SizedBox(height: 37),
],
@@ -85,18 +79,6 @@ class _SettingPageState extends State<SettingPage> {
);
}
Widget _buildTitle(String text) {
return Padding(
padding: const EdgeInsets.only(top: 23, bottom: 17),
child: Center(
child: Text(
text,
style: UIs.textGrey,
),
),
);
}
Widget _buildApp() {
final specific = _buildPlatformSetting();
final children = [
@@ -216,10 +198,6 @@ class _SettingPageState extends State<SettingPage> {
title: Text(
l10n.updateServerStatusInterval,
),
subtitle: Text(
l10n.willTakEeffectImmediately,
style: UIs.textGrey,
),
onTap: () async {
final val = await context.showPickSingleDialog(
title: l10n.setting,
@@ -284,12 +262,7 @@ class _SettingPageState extends State<SettingPage> {
children: children,
);
}),
actions: [
TextButton(
onPressed: () => _onSaveColor(ctrl.text),
child: Text(l10n.ok),
),
],
actions: Btn.ok(onTap: (c) => _onSaveColor(ctrl.text)).toList,
);
},
);
@@ -298,7 +271,7 @@ class _SettingPageState extends State<SettingPage> {
void _onSaveColor(String s) {
final color = s.hexToColor;
if (color == null) {
context.showSnackBar(l10n.failed);
context.showSnackBar(libL10n.fail);
return;
}
// Change [primaryColor] first, then change [_selectedColorValue],
@@ -354,13 +327,7 @@ class _SettingPageState extends State<SettingPage> {
return ValBuilder(
listenable: _setting.maxRetryCount.listenable(),
builder: (val) => ListTile(
title: Text(
l10n.maxRetryCount,
textAlign: TextAlign.start,
),
subtitle: Text(
val == 0 ? l10n.maxRetryCountEqual0 : l10n.canPullRefresh,
style: UIs.textGrey),
title: Text(l10n.maxRetryCount),
onTap: () async {
final selected = await context.showPickSingleDialog(
title: l10n.maxRetryCount,
@@ -411,9 +378,9 @@ class _SettingPageState extends State<SettingPage> {
String _buildThemeModeStr(int n) {
switch (n) {
case 1:
return l10n.light;
return libL10n.bright;
case 2:
return l10n.dark;
return libL10n.dark;
case 3:
return 'AMOLED';
case 4:
@@ -429,7 +396,7 @@ class _SettingPageState extends State<SettingPage> {
leading: const Icon(MingCute.font_fill),
title: Text(l10n.font),
trailing: Text(
fontName ?? l10n.notSelected,
fontName ?? libL10n.empty,
style: UIs.text15,
),
onTap: () {
@@ -438,7 +405,7 @@ class _SettingPageState extends State<SettingPage> {
actions: [
TextButton(
onPressed: () async => await _pickFontFile(),
child: Text(l10n.pickFile),
child: Text(libL10n.file),
),
TextButton(
onPressed: () {
@@ -446,7 +413,7 @@ class _SettingPageState extends State<SettingPage> {
context.pop();
RNodes.app.notify();
},
child: Text(l10n.clear),
child: Text(libL10n.clear),
)
],
);
@@ -536,7 +503,7 @@ class _SettingPageState extends State<SettingPage> {
final selected = await context.showPickSingleDialog(
title: l10n.language,
items: AppLocalizations.supportedLocales,
name: (p0) => '${p0.nativeDisplayLanguage} (${p0.code})',
name: (p0) => p0.nativeName,
initial: _setting.locale.fetch().toLocale,
);
if (selected != null) {
@@ -548,7 +515,7 @@ class _SettingPageState extends State<SettingPage> {
trailing: ListenBuilder(
listenable: _setting.locale.listenable(),
builder: () => Text(
l10n.languageName,
context.localeNativeName,
style: UIs.text15,
),
),
@@ -567,7 +534,7 @@ class _SettingPageState extends State<SettingPage> {
Widget _buildEditorTheme() {
return ListTile(
leading: const Icon(MingCute.sun_fill),
title: Text('${l10n.light} ${l10n.theme.toLowerCase()}'),
title: Text('${libL10n.bright} ${l10n.theme.toLowerCase()}'),
trailing: ValBuilder(
listenable: _setting.editorTheme.listenable(),
builder: (val) => Text(val, style: UIs.text15),
@@ -589,7 +556,7 @@ class _SettingPageState extends State<SettingPage> {
Widget _buildEditorDarkTheme() {
return ListTile(
leading: const Icon(MingCute.moon_stars_fill),
title: Text('${l10n.dark} ${l10n.theme.toLowerCase()}'),
title: Text('${libL10n.dark} ${l10n.theme.toLowerCase()}'),
trailing: ValBuilder(
listenable: _setting.editorDarkTheme.listenable(),
builder: (val) => Text(val, style: UIs.text15),
@@ -671,14 +638,6 @@ class _SettingPageState extends State<SettingPage> {
// );
// }
// Widget _buildCNKeyboardComp() {
// return ListTile(
// title: Text(l10n.cnKeyboardComp),
// subtitle: Text(l10n.cnKeyboardCompTip, style: UIs.textGrey),
// trailing: StoreSwitch(prop: _setting.cnKeyboardComp),
// );
// }
Widget _buildSSHVirtKeys() {
return ListTile(
leading: const Icon(BoxIcons.bxs_keyboard),
@@ -765,7 +724,7 @@ class _SettingPageState extends State<SettingPage> {
final md = deleteKeys.map((e) => '- $e').join('\n');
final sure = await context.showRoundDialog(
title: l10n.attention,
title: libL10n.attention,
child: SimpleMarkdown(data: md),
);
@@ -805,12 +764,7 @@ class _SettingPageState extends State<SettingPage> {
onSubmitted: _onSaveTextScaler,
suggestion: false,
),
actions: [
TextButton(
onPressed: () => _onSaveTextScaler(ctrl.text),
child: Text(l10n.ok),
),
],
actions: Btn.ok(onTap: (c) => _onSaveTextScaler(ctrl.text)).toList,
),
);
}
@@ -818,7 +772,7 @@ class _SettingPageState extends State<SettingPage> {
void _onSaveTextScaler(String s) {
final val = double.tryParse(s);
if (val == null) {
context.showSnackBar(l10n.failed);
context.showSnackBar(libL10n.fail);
return;
}
_setting.textFactor.put(val);
@@ -897,7 +851,7 @@ class _SettingPageState extends State<SettingPage> {
final fontSize = double.tryParse(ctrller.text);
if (fontSize == null) {
context.showRoundDialog(
title: l10n.failed,
title: libL10n.fail,
child: Text('Parsed failed: ${ctrller.text}'),
);
return;
@@ -915,20 +869,14 @@ class _SettingPageState extends State<SettingPage> {
suggestion: false,
onSubmitted: (_) => onSave(),
),
actions: [
TextButton(
onPressed: onSave,
child: Text(l10n.ok),
),
],
actions: Btn.ok(onTap: (c) => onSave()).toList,
);
}
Widget _buildSftpRmrDir() {
return ListTile(
leading: const Icon(MingCute.delete_2_fill),
title: const Text('rm -r'),
subtitle: Text(l10n.sftpRmrDirSummary, style: UIs.textGrey),
title: TipText(text: 'rm -r', tip: l10n.sftpRmrDirSummary),
trailing: StoreSwitch(prop: _setting.sftpRmrDir),
);
}
@@ -975,8 +923,7 @@ class _SettingPageState extends State<SettingPage> {
Widget _buildCollapseUI() {
return ListTile(
title: Text(l10n.collapseUI),
subtitle: Text(l10n.collapseUITip, style: UIs.textGrey),
title: TipText(text: 'UI ${libL10n.fold}', tip: l10n.collapseUITip),
trailing: StoreSwitch(prop: _setting.collapseUIDefault),
);
}
@@ -1054,11 +1001,11 @@ class _SettingPageState extends State<SettingPage> {
case 0:
return l10n.system;
case 1:
return l10n.light;
return libL10n.bright;
case 2:
return l10n.dark;
return libL10n.dark;
default:
return l10n.error;
return libL10n.error;
}
}
@@ -1161,14 +1108,9 @@ class _SettingPageState extends State<SettingPage> {
void onSave(String url) {
if (url.isEmpty || !url.startsWith('http')) {
context.showRoundDialog(
title: l10n.failed,
title: libL10n.fail,
child: Text('${l10n.invalid} URL'),
actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(l10n.ok),
),
],
actions: Btn.ok(onTap: (c) => context.pop()).toList,
);
return;
}
@@ -1198,18 +1140,13 @@ class _SettingPageState extends State<SettingPage> {
onSubmitted: onSave,
),
ListTile(
title: Text(l10n.doc),
title: Text(libL10n.doc),
trailing: const Icon(Icons.open_in_new),
onTap: () => Urls.appWiki.launch(),
),
],
),
actions: [
TextButton(
onPressed: () => onSave(ctrl.text),
child: Text(l10n.ok),
),
],
actions: Btn.ok(onTap: (c) => onSave(ctrl.text)).toList,
);
},
);
@@ -1217,8 +1154,7 @@ class _SettingPageState extends State<SettingPage> {
Widget _buildBeta() {
return ListTile(
title: const Text('Beta Program'),
subtitle: Text(l10n.acceptBeta, style: UIs.textGrey),
title: TipText(text: 'Beta Program', tip: l10n.acceptBeta),
trailing: StoreSwitch(prop: _setting.betaTest),
);
}
@@ -1258,7 +1194,7 @@ class _SettingPageState extends State<SettingPage> {
}
await context.showRoundDialog<bool>(
title: l10n.choose,
title: libL10n.select,
child: Input(
controller: ctrl,
autoFocus: true,

View File

@@ -15,9 +15,7 @@ class _AndroidSettingsPageState extends State<AndroidSettingsPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: const CustomAppBar(
title: Text('Android'),
),
appBar: const CustomAppBar(title: Text('Android')),
body: ListView(
padding: const EdgeInsets.symmetric(horizontal: 17),
children: [

View File

@@ -21,9 +21,7 @@ class _IOSSettingsPageState extends State<IOSSettingsPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: const CustomAppBar(
title: Text('iOS'),
),
appBar: const CustomAppBar(title: Text('iOS')),
body: ListView(
padding: const EdgeInsets.symmetric(horizontal: 17),
children: [
@@ -45,22 +43,23 @@ class _IOSSettingsPageState extends State<IOSSettingsPage> {
alignment: Alignment.centerRight,
padding: EdgeInsets.zero,
onPressed: () {
if (_pushToken.value != null) {
Pfs.copy(_pushToken.value!);
final val = _pushToken.value;
if (val != null) {
Pfs.copy(val);
context.showSnackBar(l10n.success);
} else {
context.showSnackBar(l10n.getPushTokenFailed);
context.showSnackBar(libL10n.fail);
}
},
),
subtitle: FutureWidget<String?>(
future: getToken(),
loading: Text(l10n.gettingToken),
error: (error, trace) => Text('${l10n.error}: $error'),
loading: const Text('...'),
error: (error, trace) => Text('${libL10n.error}: $error'),
success: (text) {
_pushToken.value = text;
return Text(
text ?? l10n.nullToken,
text ?? 'null',
style: UIs.textGrey,
overflow: TextOverflow.ellipsis,
maxLines: 1,
@@ -89,7 +88,7 @@ class _IOSSettingsPageState extends State<IOSSettingsPage> {
Loggers.app.warning('WatchOS error', e, trace);
return ListTile(
title: const Text('Watch app'),
subtitle: Text('${l10n.error}: $e', style: UIs.textGrey),
subtitle: Text('${libL10n.error}: $e', style: UIs.textGrey),
);
},
success: (ctx) {

View File

@@ -9,16 +9,16 @@ abstract final class PlatformPublicSettings {
return FutureWidget<bool>(
future: BioAuth.isAvail,
loading: ListTile(
title: Text(l10n.bioAuth),
subtitle: Text(l10n.serverTabLoading, style: UIs.textGrey),
title: Text(libL10n.bioAuth),
subtitle: const Text('...', style: UIs.textGrey),
),
error: (e, __) => ListTile(
title: Text(l10n.bioAuth),
subtitle: Text('${l10n.failed}: $e', style: UIs.textGrey),
title: Text(libL10n.bioAuth),
subtitle: Text('${libL10n.fail}: $e', style: UIs.textGrey),
),
success: (can) {
return ListTile(
title: Text(l10n.bioAuth),
title: Text(libL10n.bioAuth),
subtitle: can == true
? null
: const Text(

View File

@@ -17,9 +17,7 @@ class _ServerDetailOrderPageState extends State<ServerDetailOrderPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: Text(l10n.serverDetailOrder),
),
appBar: CustomAppBar(title: Text(l10n.serverDetailOrder)),
body: _buildBody(),
);
}
@@ -52,7 +50,7 @@ class _ServerDetailOrderPageState extends State<ServerDetailOrderPage> {
itemCount: allKeys.length,
onReorder: (o, n) {
if (o >= keys.length || n >= keys.length) {
context.showSnackBar(l10n.disabled);
context.showSnackBar(libL10n.disabled);
return;
}
keys.moveByItem(o, n, property: prop);

View File

@@ -17,9 +17,7 @@ class _ServerDetailOrderPageState extends State<ServerFuncBtnsOrderPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: Text(l10n.sequence),
),
appBar: CustomAppBar(title: Text(l10n.sequence)),
body: _buildBody(),
);
}
@@ -57,7 +55,7 @@ class _ServerDetailOrderPageState extends State<ServerFuncBtnsOrderPage> {
itemCount: allKeys.length,
onReorder: (o, n) {
if (o >= keys.length || n >= keys.length) {
context.showSnackBar(l10n.disabled);
context.showSnackBar(libL10n.disabled);
return;
}
keys.moveByItem(o, n, property: prop);

View File

@@ -16,9 +16,7 @@ class _ServerOrderPageState extends State<ServerOrderPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: Text(l10n.serverOrder),
),
appBar: CustomAppBar(title: Text(l10n.serverOrder)),
body: _buildBody(),
);
}
@@ -48,7 +46,7 @@ class _ServerOrderPageState extends State<ServerOrderPage> {
Widget _buildBody() {
if (Pros.server.serverOrder.isEmpty) {
return Center(child: Text(l10n.noServerAvailable));
return Center(child: Text(libL10n.empty));
}
return ReorderableListView.builder(
footer: const SizedBox(height: 77),

View File

@@ -17,9 +17,7 @@ class _SSHVirtKeySettingPageState extends State<SSHVirtKeySettingPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: Text(l10n.editVirtKeys),
),
appBar: CustomAppBar(title: Text(l10n.editVirtKeys)),
body: Column(
children: [
Padding(
@@ -67,7 +65,7 @@ class _SSHVirtKeySettingPageState extends State<SSHVirtKeySettingPage> {
itemCount: allKeys.length,
onReorder: (o, n) {
if (o >= keys.length || n >= keys.length) {
context.showSnackBar(l10n.disabled);
context.showSnackBar(libL10n.disabled);
return;
}
keys.moveByItem(o, n, property: prop);

View File

@@ -1,13 +1,9 @@
import 'dart:convert';
import 'package:computer/computer.dart';
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:server_box/core/extension/context/locale.dart';
import 'package:server_box/data/model/server/snippet.dart';
import 'package:server_box/data/res/provider.dart';
import 'package:icons_plus/icons_plus.dart';
class SnippetEditPage extends StatefulWidget {
const SnippetEditPage({super.key, this.snippet});
@@ -39,7 +35,7 @@ class _SnippetEditPageState extends State<SnippetEditPage>
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: Text(l10n.edit),
title: Text(libL10n.edit),
actions: _buildAppBarActions(),
),
body: _buildBody(),
@@ -53,23 +49,21 @@ class _SnippetEditPageState extends State<SnippetEditPage>
IconButton(
onPressed: () {
context.showRoundDialog(
title: l10n.attention,
child: Text(l10n.askContinue(
'${l10n.delete} ${l10n.snippet}(${widget.snippet!.name})',
title: libL10n.attention,
child: Text(libL10n.askContinue(
'${libL10n.delete} ${l10n.snippet}(${widget.snippet!.name})',
)),
actions: [
TextButton(
onPressed: () {
actions: Btn.ok(
onTap: (c) {
Pros.snippet.del(widget.snippet!);
context.pop();
context.pop();
},
child: Text(l10n.ok, style: UIs.textRed),
),
],
red: true,
).toList,
);
},
tooltip: l10n.delete,
tooltip: libL10n.delete,
icon: const Icon(Icons.delete),
)
];
@@ -83,7 +77,7 @@ class _SnippetEditPageState extends State<SnippetEditPage>
final name = _nameController.text;
final script = _scriptController.text;
if (name.isEmpty || script.isEmpty) {
context.showSnackBar(l10n.fieldMustNotEmpty);
context.showSnackBar(libL10n.empty);
return;
}
final note = _noteController.text;
@@ -108,13 +102,12 @@ class _SnippetEditPageState extends State<SnippetEditPage>
return ListView(
padding: const EdgeInsets.symmetric(horizontal: 13),
children: [
_buildImport(),
Input(
autoFocus: true,
controller: _nameController,
type: TextInputType.text,
onSubmitted: (_) => FocusScope.of(context).requestFocus(_scriptNode),
label: l10n.name,
label: libL10n.name,
icon: Icons.info,
suggestion: true,
),
@@ -188,65 +181,6 @@ class _SnippetEditPageState extends State<SnippetEditPage>
);
}
Widget _buildImport() {
return Btn.tile(
text: l10n.import,
icon: const Icon(BoxIcons.bx_import),
onTap: (c) async {
final data = await c.showImportDialog(
title: l10n.snippet,
modelDef: Snippet.example.toJson(),
);
if (data == null) return;
final str = String.fromCharCodes(data);
final (list, _) = await context.showLoadingDialog(
fn: () => Computer.shared.start((s) {
return json.decode(s) as List;
}, str),
);
if (list == null || list.isEmpty) return;
final snippets = <Snippet>[];
final errs = <String>[];
for (final item in list) {
try {
final snippet = Snippet.fromJson(item);
snippets.add(snippet);
} catch (e) {
errs.add(e.toString());
}
}
if (snippets.isEmpty) {
c.showSnackBar(libL10n.empty);
return;
}
if (errs.isNotEmpty) {
c.showRoundDialog(
title: l10n.error,
child: SingleChildScrollView(child: Text(errs.join('\n'))),
);
return;
}
final snippetNames = snippets.map((e) => e.name).join(', ');
c.showRoundDialog(
title: l10n.attention,
child: SingleChildScrollView(
child: Text(l10n.askContinue('${l10n.import} [$snippetNames]')),
),
actions: Btn.ok(
onTap: (c) {
for (final snippet in snippets) {
Pros.snippet.add(snippet);
}
c.pop();
context.pop();
},
).toList,
);
},
mainAxisAlignment: MainAxisAlignment.center,
);
}
Widget _buildTip() {
return CardX(
child: Padding(
@@ -257,7 +191,7 @@ class _SnippetEditPageState extends State<SnippetEditPage>
${Snippet.fmtArgs.keys.map((e) => '`$e`').join(', ')}\n
${Snippet.fmtTermKeys.keys.map((e) => '`$e+?}`').join(', ')}\n
${l10n.forExample}:
${libL10n.example}:
- `\${ctrl+c}` (Control + C)
- `\${ctrl+b}d` (Tmux Detach)
''',

View File

@@ -1,7 +1,6 @@
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:server_box/core/extension/context/locale.dart';
import 'package:server_box/data/res/store.dart';
import '../../../data/model/server/snippet.dart';
@@ -42,9 +41,7 @@ class _SnippetListPageState extends State<SnippetListPage> {
return Consumer<SnippetProvider>(
builder: (_, provider, __) {
if (provider.snippets.isEmpty) {
return Center(
child: Text(l10n.noSavedSnippet),
);
return Center(child: Text(libL10n.empty));
}
final filtered = provider.snippets

View File

@@ -11,9 +11,7 @@ class SnippetResultPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: Text(l10n.result),
),
appBar: CustomAppBar(title: Text(l10n.result)),
body: _buildBody(),
);
}

View File

@@ -325,7 +325,7 @@ class SSHPageState extends State<SSHPage>
final initPath = cmds[idx + 1].toString();
if (initPath.isEmpty || !initPath.startsWith('/')) {
context.showRoundDialog(
title: l10n.error,
title: libL10n.error,
child: const Text('Failed to get current path'),
);
return;
@@ -524,7 +524,7 @@ class SSHPageState extends State<SSHPage>
if (Stores.setting.sshTermHelpShown.fetch()) return;
return await context.showRoundDialog(
title: l10n.doc,
title: libL10n.doc,
child: Text(l10n.sshTermHelp),
actions: [
TextButton(

View File

@@ -22,7 +22,7 @@ typedef _TabMap = Map<String, ({Widget page, GlobalKey<SSHPageState>? key})>;
class _SSHTabPageState extends State<SSHTabPage>
with TickerProviderStateMixin, AutomaticKeepAliveClientMixin {
late final _TabMap _tabMap = {
l10n.add: (page: _buildAddPage(), key: null),
libL10n.add: (page: _buildAddPage(), key: null),
};
final _pageCtrl = PageController();
final _fabVN = 0.vn;
@@ -51,7 +51,7 @@ class _SSHTabPageState extends State<SSHTabPage>
return FloatingActionButton(
heroTag: 'sshAddServer',
onPressed: () => AppRoutes.serverEdit().go(context),
tooltip: l10n.addAServer,
tooltip: libL10n.add,
child: const Icon(Icons.add),
);
},
@@ -71,16 +71,15 @@ class _SSHTabPageState extends State<SSHTabPage>
context: context,
builder: (context) {
return AlertDialog(
title: Text(l10n.attention),
content: Text('${l10n.close} SSH ${l10n.conn}($name) ?'),
title: Text(libL10n.attention),
content: Text('${libL10n.close} SSH ${l10n.conn}($name) ?'),
actions: [
TextButton(
onPressed: () => context.pop(true),
child: Text(l10n.ok, style: UIs.textRed),
Btn.ok(
onTap: (c) => context.pop(true),
red: true,
),
TextButton(
onPressed: () => context.pop(false),
child: Text(l10n.cancel),
Btn.cancel(
onTap: (c) => context.pop(false),
),
],
);
@@ -101,10 +100,7 @@ class _SSHTabPageState extends State<SSHTabPage>
child: Consumer<ServerProvider>(builder: (_, pro, __) {
if (pro.serverOrder.isEmpty) {
return Center(
child: Text(
l10n.serverTabEmpty,
textAlign: TextAlign.center,
),
child: Text(libL10n.empty, textAlign: TextAlign.center),
);
}
return GridView.builder(

View File

@@ -57,7 +57,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
context.pop();
},
),
title: Text(l10n.files),
title: Text(libL10n.file),
actions: [
IconButton(
icon: const Icon(Icons.downloading),
@@ -72,7 +72,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
return [
PopupMenuItem(
value: _SortType.name,
child: Text(l10n.name),
child: Text(libL10n.name),
),
PopupMenuItem(
value: _SortType.size,
@@ -111,7 +111,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
OmitStartText(_path?.path ?? l10n.loadingFiles),
OmitStartText(_path?.path ?? '...'),
_buildBtns(),
],
),
@@ -203,7 +203,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
context.pop();
_showRenameDialog(file);
},
title: Text(l10n.rename),
title: Text(libL10n.rename),
leading: const Icon(Icons.abc),
),
ListTile(
@@ -211,7 +211,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
context.pop();
_showDeleteDialog(file);
},
title: Text(l10n.delete),
title: Text(libL10n.delete),
leading: const Icon(Icons.delete),
),
],
@@ -223,17 +223,15 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
final fileName = file.path.split('/').last;
if (widget.isPickFile) {
await context.showRoundDialog(
title: l10n.pickFile,
title: libL10n.file,
child: Text(fileName),
actions: [
TextButton(
onPressed: () {
Btn.ok(onTap: (c) {
context.pop();
context.pop(file.path);
},
child: Text(l10n.ok),
),
]);
}),
],
);
return;
}
context.showRoundDialog(
@@ -242,13 +240,13 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
children: [
ListTile(
leading: const Icon(Icons.edit),
title: Text(l10n.edit),
title: Text(libL10n.edit),
onTap: () async {
context.pop();
final stat = await file.stat();
if (stat.size > Miscs.editorMaxSize) {
context.showRoundDialog(
title: l10n.attention,
title: libL10n.attention,
child: Text(l10n.fileTooLarge(fileName, stat.size, '1m')),
);
return;
@@ -264,7 +262,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
),
ListTile(
leading: const Icon(Icons.abc),
title: Text(l10n.rename),
title: Text(libL10n.rename),
onTap: () {
context.pop();
_showRenameDialog(file);
@@ -272,7 +270,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
),
ListTile(
leading: const Icon(Icons.delete),
title: Text(l10n.delete),
title: Text(libL10n.delete),
onTap: () {
context.pop();
_showDeleteDialog(file);
@@ -285,7 +283,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
context.pop();
final spi = await context.showPickSingleDialog<ServerPrivateInfo>(
title: l10n.choose,
title: libL10n.select,
items: Pros.server.serverOrder
.map((e) => Pros.server.pick(id: e)?.spi)
.toList(),
@@ -325,7 +323,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
void _showRenameDialog(FileSystemEntity file) {
final fileName = file.path.split('/').last;
context.showRoundDialog(
title: l10n.rename,
title: libL10n.rename,
child: Input(
autoFocus: true,
controller: TextEditingController(text: fileName),
@@ -336,7 +334,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
try {
file.renameSync(newPath);
} catch (e) {
context.showSnackBar('${l10n.failed}:\n$e');
context.showSnackBar('${libL10n.fail}:\n$e');
return;
}
@@ -349,27 +347,20 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
void _showDeleteDialog(FileSystemEntity file) {
final fileName = file.path.split('/').last;
context.showRoundDialog(
title: l10n.delete,
child: Text(l10n.askContinue('${l10n.delete} $fileName')),
actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(l10n.cancel),
),
TextButton(
onPressed: () {
title: libL10n.delete,
child: Text(libL10n.askContinue('${libL10n.delete} $fileName')),
actions: Btn.ok(
onTap: (c) {
context.pop();
try {
file.deleteSync(recursive: true);
} catch (e) {
context.showSnackBar('${l10n.failed}:\n$e');
context.showSnackBar('${libL10n.fail}:\n$e');
return;
}
setState(() {});
},
child: Text(l10n.ok),
),
],
).toList,
);
}
}

View File

@@ -69,7 +69,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
itemBuilder: (context) {
final currentSelectedOption = _sortOption.value;
final options = [
(_SortType.name, l10n.name),
(_SortType.name, libL10n.name),
(_SortType.size, l10n.size),
(_SortType.time, l10n.time),
];
@@ -142,7 +142,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
OmitStartText(_status.path?.path ?? l10n.loadingFiles),
OmitStartText(_status.path?.path ?? '...'),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: children,
@@ -232,12 +232,12 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
children: [
ListTile(
leading: const Icon(Icons.folder),
title: Text(l10n.createFolder),
title: Text(libL10n.folder),
onTap: _mkdir,
),
ListTile(
leading: const Icon(Icons.insert_drive_file),
title: Text(l10n.createFile),
title: Text(libL10n.file),
onTap: _newFile,
),
],
@@ -369,12 +369,12 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
final children = [
ListTile(
leading: const Icon(Icons.delete),
title: Text(l10n.delete),
title: Text(libL10n.delete),
onTap: () => _delete(file),
),
ListTile(
leading: const Icon(Icons.abc),
title: Text(l10n.rename),
title: Text(libL10n.rename),
onTap: () => _rename(file),
),
ListTile(
@@ -413,12 +413,12 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
children.addAll([
ListTile(
leading: const Icon(Icons.edit),
title: Text(l10n.edit),
title: Text(libL10n.edit),
onTap: () => _edit(file),
),
ListTile(
leading: const Icon(Icons.download),
title: Text(l10n.download),
title: Text(libL10n.download),
onTap: () => _download(file),
),
// Only show decompress option when the file is a compressed file
@@ -490,12 +490,12 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
void _download(SftpName name) {
context.showRoundDialog(
title: l10n.attention,
title: libL10n.attention,
child: Text('${l10n.dl2Local(name.filename)}\n${l10n.keepForeground}'),
actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(l10n.cancel),
child: Text(libL10n.cancel),
),
TextButton(
onPressed: () async {
@@ -513,7 +513,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
context.pop();
},
child: Text(l10n.download),
child: Text(libL10n.download),
)
],
);
@@ -525,15 +525,15 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
var useRmr = Stores.setting.sftpRmrDir.fetch();
final text = () {
if (isDir && !useRmr) {
return l10n.askContinue('${l10n.delete} ${file.filename}');
return libL10n.askContinue('${libL10n.delete} ${file.filename}');
}
return l10n.askContinue('${l10n.delete} ${file.filename}');
return libL10n.askContinue('${libL10n.delete} ${file.filename}');
}();
// Most users don't know that SFTP can't delete a directory which is not
// empty, so we provide a checkbox to let user choose to use `rm -r` or not
context.showRoundDialog(
title: l10n.attention,
title: libL10n.attention,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
@@ -560,7 +560,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(l10n.cancel),
child: Text(libL10n.cancel),
),
TextButton(
onPressed: () async {
@@ -583,7 +583,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
_listDir();
},
child: Text(l10n.delete, style: UIs.textRed),
child: Text(libL10n.delete, style: UIs.textRed),
),
],
);
@@ -596,13 +596,8 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
void onSubmitted() async {
if (textController.text.isEmpty) {
context.showRoundDialog(
child: Text(l10n.fieldMustNotEmpty),
actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(l10n.ok),
),
],
child: Text(libL10n.empty),
actions: Btnx.oks,
);
return;
}
@@ -621,25 +616,19 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
}
context.showRoundDialog(
title: l10n.createFolder,
title: libL10n.folder,
child: Input(
autoFocus: true,
icon: Icons.folder,
controller: textController,
label: l10n.name,
label: libL10n.name,
suggestion: true,
onSubmitted: (_) => onSubmitted(),
),
actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(l10n.cancel),
),
TextButton(
onPressed: onSubmitted,
child: Text(l10n.ok, style: UIs.textRed),
),
],
actions: Btn.ok(
onTap: (c) => onSubmitted(),
red: true,
).toList,
);
}
@@ -650,14 +639,11 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
void onSubmitted() async {
if (textController.text.isEmpty) {
context.showRoundDialog(
title: l10n.attention,
child: Text(l10n.fieldMustNotEmpty),
actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(l10n.ok),
),
],
title: libL10n.attention,
child: Text(libL10n.empty),
actions: Btn.ok(
onTap: (c) => context.pop(),
).toList,
);
return;
}
@@ -676,21 +662,19 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
}
context.showRoundDialog(
title: l10n.createFile,
title: libL10n.file,
child: Input(
autoFocus: true,
icon: Icons.insert_drive_file,
controller: textController,
label: l10n.name,
label: libL10n.name,
suggestion: true,
onSubmitted: (_) => onSubmitted(),
),
actions: [
TextButton(
onPressed: onSubmitted,
child: Text(l10n.ok, style: UIs.textRed),
),
],
actions: Btn.ok(
onTap: (c) => onSubmitted(),
red: true,
).toList,
);
}
@@ -701,14 +685,11 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
void onSubmitted() async {
if (textController.text.isEmpty) {
context.showRoundDialog(
title: l10n.attention,
child: Text(l10n.fieldMustNotEmpty),
actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(l10n.ok),
),
],
title: libL10n.attention,
child: Text(libL10n.empty),
actions: Btn.ok(
onTap: (c) => context.pop(),
).toList,
);
return;
}
@@ -727,20 +708,20 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
}
context.showRoundDialog(
title: l10n.rename,
title: libL10n.rename,
child: Input(
autoFocus: true,
icon: Icons.abc,
controller: textController,
label: l10n.name,
label: libL10n.name,
suggestion: true,
onSubmitted: (_) => onSubmitted(),
),
actions: [
TextButton(onPressed: () => context.pop(), child: Text(l10n.cancel)),
TextButton(onPressed: () => context.pop(), child: Text(libL10n.cancel)),
TextButton(
onPressed: onSubmitted,
child: Text(l10n.rename, style: UIs.textRed),
child: Text(libL10n.rename, style: UIs.textRed),
),
],
);
@@ -752,7 +733,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
final cmd = _getDecompressCmd(absPath);
if (cmd == null) {
context.showRoundDialog(
title: l10n.error,
title: libL10n.error,
child: Text('Unsupport file: ${name.filename}'),
actions: [Btn.ok()],
);
@@ -760,7 +741,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
}
final confirm = await context.showRoundDialog(
title: l10n.attention,
title: libL10n.attention,
child: SimpleMarkdown(data: '```sh\n$cmd\n```'),
actions: [
Btn.cancel(onTap: (c) => c.pop(false)),

View File

@@ -28,9 +28,7 @@ class _SftpMissionPageState extends State<SftpMissionPage> {
Widget _buildBody() {
return Consumer<SftpProvider>(builder: (__, pro, _) {
if (pro.status.isEmpty) {
return Center(
child: Text(l10n.noTask),
);
return Center(child: Text(libL10n.empty));
}
return ListView.builder(
padding: const EdgeInsets.all(11),
@@ -48,10 +46,10 @@ class _SftpMissionPageState extends State<SftpMissionPage> {
if (err != null) {
return _wrapInCard(
status: status,
subtitle: l10n.error,
subtitle: libL10n.error,
trailing: IconButton(
onPressed: () => context.showRoundDialog(
title: l10n.error,
title: libL10n.error,
child: Text(err.toString()),
),
icon: const Icon(Icons.error),
@@ -81,7 +79,7 @@ class _SftpMissionPageState extends State<SftpMissionPage> {
subtitle: l10n.unknown,
trailing: IconButton(
onPressed: () => context.showRoundDialog(
title: l10n.error,
title: libL10n.error,
child: Text((status.error ?? l10n.unknown).toString()),
),
icon: const Icon(Icons.error),
@@ -109,9 +107,9 @@ class _SftpMissionPageState extends State<SftpMissionPage> {
Widget _buildFinished(SftpReqStatus status) {
final time = status.spentTime.toString();
final str = '${l10n.finished} ${l10n.spentTime(
final str = l10n.spentTime(
time == 'null' ? l10n.unknown : (time.substring(0, time.length - 7)),
)}';
);
final btns = Row(
mainAxisSize: MainAxisSize.min,
@@ -161,19 +159,17 @@ class _SftpMissionPageState extends State<SftpMissionPage> {
Widget _buildDelete(String name, int id) {
return IconButton(
onPressed: () => context.showRoundDialog(
title: l10n.attention,
child: Text(l10n.askContinue(
'${l10n.delete} ${l10n.mission}($name)',
title: libL10n.attention,
child: Text(libL10n.askContinue(
'${libL10n.delete} ${l10n.mission}($name)',
)),
actions: [
TextButton(
onPressed: () {
actions: Btn.ok(
onTap: (c) {
Pros.sftp.cancel(id);
context.pop();
},
child: Text(l10n.ok),
).toList,
),
]),
icon: const Icon(Icons.delete),
);
}

View File

@@ -104,7 +104,7 @@ void _onTapMoreBtns(
break;
case ServerFuncBtn.snippet:
if (Pros.snippet.snippets.isEmpty) {
context.showSnackBar(l10n.noSavedSnippet);
context.showSnackBar(libL10n.empty);
return;
}
final snippets = await context.showPickWithTagDialog<Snippet>(
@@ -123,7 +123,7 @@ void _onTapMoreBtns(
if (snippet == null) return;
final fmted = snippet.fmtWithSpi(spi);
final sure = await context.showRoundDialog<bool>(
title: l10n.attention,
title: libL10n.attention,
child: SingleChildScrollView(
child: SimpleMarkdown(data: '```shell\n$fmted\n```'),
),
@@ -219,87 +219,3 @@ bool _checkClient(BuildContext context, String id) {
}
return true;
}
// Future<void> _onPkg(BuildContext context, ServerPrivateInfo spi) async {
// final server = spi.server;
// final client = server?.client;
// if (server == null || client == null) {
// context.showSnackBar(l10n.noClient);
// return;
// }
// final sys = server.status.more[StatusCmdType.sys];
// if (sys == null) {
// context.showSnackBar(l10n.noResult);
// return;
// }
// final pkg = PkgManager.fromDist(sys.dist);
// if (pkg == null) {
// context.showSnackBar('Unsupported dist: $sys');
// return;
// }
// // Update pkg list
// final suc = await context.showLoadingDialog(
// fn: () async {
// final updateCmd = pkg.update;
// if (updateCmd != null) {
// await client.execWithPwd(
// updateCmd,
// context: context,
// id: spi.id,
// );
// }
// },
// barrierDismiss: true,
// );
// if (suc != true) return;
// final listCmd = pkg.listUpdate;
// if (listCmd == null) {
// context.showSnackBar('Unsupported dist: $sys');
// return;
// }
// // Get upgrade list
// final result = await context.showLoadingDialog(
// fn: () => client.run(listCmd).string,
// );
// if (result == null || result.isEmpty) {
// context.showSnackBar(l10n.noResult);
// return;
// }
// final list = pkg.updateListRemoveUnused(result.split('\n'));
// final upgradeable = list.map((e) => UpgradePkgInfo(e, pkg)).toList();
// if (upgradeable.isEmpty) {
// context.showSnackBar(l10n.noUpdateAvailable);
// return;
// }
// final args = upgradeable.map((e) => e.package).join(' ');
// final isSU = server.spi.user == 'root';
// final upgradeCmd = isSU ? pkg.upgrade(args) : 'sudo ${pkg.upgrade(args)}';
// // Confirm upgrade
// final gotoUpgrade = await context.showRoundDialog<bool>(
// title: l10n.attention,
// child: SingleChildScrollView(
// child: Text(
// '${l10n.pkgUpgradeTip}\n${l10n.foundNUpdate(upgradeable.length)}\n\n$upgradeCmd'),
// ),
// actions: [
// CountDownBtn(
// onTap: () => context.pop(true),
// text: l10n.update,
// afterColor: Colors.red,
// ),
// ],
// );
// if (gotoUpgrade != true) return;
// AppRoutes.ssh(spi: spi, initCmd: upgradeCmd).checkGo(
// context: context,
// check: () => _checkClient(context, spi.id),
// );
// }

View File

@@ -385,8 +385,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: "v1.0.106"
resolved-ref: "31735eee1d42e6bcb6c3ccd061047401b4a23421"
ref: "v1.0.109"
resolved-ref: "27266fdd805a5bb2a9c682ca70aaaef785e609b5"
url: "https://github.com/lppcg/fl_lib"
source: git
version: "0.0.1"
@@ -755,7 +755,7 @@ packages:
source: hosted
version: "1.0.10"
locale_names:
dependency: "direct main"
dependency: transitive
description:
name: locale_names
sha256: "7a89ca54072f4f13d0f5df5a9ba69337554bf2fd057d1dd2a238898f3f159374"
@@ -1055,18 +1055,18 @@ packages:
dependency: transitive
description:
name: share_plus
sha256: ef3489a969683c4f3d0239010cc8b7a2a46543a8d139e111c06c558875083544
sha256: "59dfd53f497340a0c3a81909b220cfdb9b8973a91055c4e5ab9b9b9ad7c513c0"
url: "https://pub.dev"
source: hosted
version: "9.0.0"
version: "10.0.0"
share_plus_platform_interface:
dependency: transitive
description:
name: share_plus_platform_interface
sha256: "0f9e4418835d1b2c3ae78fdb918251959106cefdbc4dd43526e182f80e82f6d4"
sha256: "6ababf341050edff57da8b6990f11f4e99eaba837865e2e6defe16d039619db5"
url: "https://pub.dev"
source: hosted
version: "4.0.0"
version: "5.0.0"
shared_preferences:
dependency: "direct main"
description:

View File

@@ -30,7 +30,6 @@ dependencies:
flutter_adaptive_scaffold: ^0.1.10+2
device_info_plus: ^10.1.0
extended_image: ^8.2.1
locale_names: ^1.1.1
dartssh2:
git:
url: https://github.com/lollipopkit/dartssh2
@@ -62,7 +61,7 @@ dependencies:
fl_lib:
git:
url: https://github.com/lppcg/fl_lib
ref: v1.0.106
ref: v1.0.109
dependency_overrides:
# dartssh2: