mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
rollback: write script to /dev/shm (#474)
This commit is contained in:
@@ -690,7 +690,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 1018;
|
CURRENT_PROJECT_VERSION = 1021;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
||||||
@@ -700,7 +700,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.1018;
|
MARKETING_VERSION = 1.0.1021;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
@@ -826,7 +826,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 1018;
|
CURRENT_PROJECT_VERSION = 1021;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
||||||
@@ -836,7 +836,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.1018;
|
MARKETING_VERSION = 1.0.1021;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
@@ -854,7 +854,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 1018;
|
CURRENT_PROJECT_VERSION = 1021;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
||||||
@@ -864,7 +864,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.1018;
|
MARKETING_VERSION = 1.0.1021;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
@@ -885,7 +885,7 @@
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1018;
|
CURRENT_PROJECT_VERSION = 1021;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -898,7 +898,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.1018;
|
MARKETING_VERSION = 1.0.1021;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
||||||
@@ -924,7 +924,7 @@
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1018;
|
CURRENT_PROJECT_VERSION = 1021;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -937,7 +937,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.1018;
|
MARKETING_VERSION = 1.0.1021;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
@@ -960,7 +960,7 @@
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1018;
|
CURRENT_PROJECT_VERSION = 1021;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -973,7 +973,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.1018;
|
MARKETING_VERSION = 1.0.1021;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
@@ -996,7 +996,7 @@
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1018;
|
CURRENT_PROJECT_VERSION = 1021;
|
||||||
DEVELOPMENT_ASSET_PATHS = "";
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
@@ -1008,7 +1008,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.1018;
|
MARKETING_VERSION = 1.0.1021;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
|
||||||
@@ -1037,7 +1037,7 @@
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1018;
|
CURRENT_PROJECT_VERSION = 1021;
|
||||||
DEVELOPMENT_ASSET_PATHS = "";
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
@@ -1049,7 +1049,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.1018;
|
MARKETING_VERSION = 1.0.1021;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
|
||||||
PRODUCT_NAME = ServerBox;
|
PRODUCT_NAME = ServerBox;
|
||||||
@@ -1075,7 +1075,7 @@
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1018;
|
CURRENT_PROJECT_VERSION = 1021;
|
||||||
DEVELOPMENT_ASSET_PATHS = "";
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
@@ -1087,7 +1087,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.1018;
|
MARKETING_VERSION = 1.0.1021;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
|
||||||
PRODUCT_NAME = ServerBox;
|
PRODUCT_NAME = ServerBox;
|
||||||
|
|||||||
@@ -19,43 +19,24 @@ enum ShellFunc {
|
|||||||
|
|
||||||
/// srvboxm -> ServerBox Mobile
|
/// srvboxm -> ServerBox Mobile
|
||||||
static const scriptFile = 'srvboxm_v${BuildData.script}.sh';
|
static const scriptFile = 'srvboxm_v${BuildData.script}.sh';
|
||||||
static const scriptPathShm = '/dev/shm/$scriptFile';
|
static const scriptDir = '~/.config/server_box';
|
||||||
static const scriptPathHome = '~/.config/server_box/$scriptFile';
|
static const scriptPath = '$scriptDir/$scriptFile';
|
||||||
|
|
||||||
static final _scriptPathMap = <String, String>{};
|
static const String installShellCmd = """
|
||||||
static String getScriptPath(String id) {
|
cat > $scriptPath
|
||||||
return _scriptPathMap.putIfAbsent(id, () => scriptPathShm);
|
chmod 744 $scriptPath
|
||||||
}
|
|
||||||
|
|
||||||
static String setScriptPath(String id, String path) {
|
|
||||||
return _scriptPathMap[id] = path;
|
|
||||||
}
|
|
||||||
static String installShellCmd(String id) {
|
|
||||||
final path = getScriptPath(id);
|
|
||||||
return """
|
|
||||||
cat > $path
|
|
||||||
chmod 744 $path
|
|
||||||
""";
|
""";
|
||||||
}
|
|
||||||
|
|
||||||
String get flag {
|
String get flag => switch (this) {
|
||||||
switch (this) {
|
ShellFunc.process => 'p',
|
||||||
case ShellFunc.status:
|
ShellFunc.shutdown => 'sd',
|
||||||
return 's';
|
ShellFunc.reboot => 'r',
|
||||||
// case ShellFunc.docker:
|
ShellFunc.suspend => 'sp',
|
||||||
// return 'd';
|
ShellFunc.status => 's',
|
||||||
case ShellFunc.process:
|
// ShellFunc.docker=> 'd',
|
||||||
return 'p';
|
};
|
||||||
case ShellFunc.shutdown:
|
|
||||||
return 'sd';
|
|
||||||
case ShellFunc.reboot:
|
|
||||||
return 'r';
|
|
||||||
case ShellFunc.suspend:
|
|
||||||
return 'sp';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String exec(String id) => 'sh ${getScriptPath(id)} -$flag';
|
String get exec => 'sh $scriptPath -$flag';
|
||||||
|
|
||||||
String get name {
|
String get name {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
|
|||||||
@@ -315,23 +315,14 @@ class ServerProvider extends ChangeNotifier {
|
|||||||
|
|
||||||
final scriptRaw = ShellFunc.allScript(spi.custom?.cmds).uint8List;
|
final scriptRaw = ShellFunc.allScript(spi.custom?.cmds).uint8List;
|
||||||
|
|
||||||
Future<void> fn(String scriptPath) async {
|
try {
|
||||||
await s.client?.runForOutput(
|
await s.client?.runForOutput(
|
||||||
scriptPath,
|
ShellFunc.installShellCmd,
|
||||||
action: (session) async {
|
action: (session) async {
|
||||||
session.stdin.add(scriptRaw);
|
session.stdin.add(scriptRaw);
|
||||||
session.stdin.close();
|
session.stdin.close();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
ShellFunc.setScriptPath(spi.id, scriptPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
try {
|
|
||||||
await fn(ShellFunc.scriptPathShm);
|
|
||||||
} catch (_) {
|
|
||||||
await fn(ShellFunc.scriptPathHome);
|
|
||||||
}
|
|
||||||
} on SSHAuthAbortError catch (e) {
|
} on SSHAuthAbortError catch (e) {
|
||||||
TryLimiter.inc(sid);
|
TryLimiter.inc(sid);
|
||||||
s.status.err = SSHErr(type: SSHErrType.auth, message: e.toString());
|
s.status.err = SSHErr(type: SSHErrType.auth, message: e.toString());
|
||||||
@@ -343,10 +334,11 @@ class ServerProvider extends ChangeNotifier {
|
|||||||
_setServerState(s, ServerConn.failed);
|
_setServerState(s, ServerConn.failed);
|
||||||
return;
|
return;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
final err = e.toString();
|
||||||
TryLimiter.inc(sid);
|
TryLimiter.inc(sid);
|
||||||
s.status.err = SSHErr(type: SSHErrType.auth, message: e.toString());
|
s.status.err = SSHErr(type: SSHErrType.writeScript, message: err);
|
||||||
_setServerState(s, ServerConn.failed);
|
_setServerState(s, ServerConn.failed);
|
||||||
Loggers.app.warning('Write script to ${spi.name} by shell', e);
|
Loggers.app.warning('Write script to ${spi.name} by shell', err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,7 +355,7 @@ class ServerProvider extends ChangeNotifier {
|
|||||||
String? raw;
|
String? raw;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
raw = await s.client?.run(ShellFunc.status.exec(spi.id)).string;
|
raw = await s.client?.run(ShellFunc.status.exec).string;
|
||||||
segments = raw?.split(ShellFunc.seperator).map((e) => e.trim()).toList();
|
segments = raw?.split(ShellFunc.seperator).map((e) => e.trim()).toList();
|
||||||
if (raw == null || raw.isEmpty || segments == null || segments.isEmpty) {
|
if (raw == null || raw.isEmpty || segments == null || segments.isEmpty) {
|
||||||
if (Stores.setting.keepStatusWhenErr.fetch()) {
|
if (Stores.setting.keepStatusWhenErr.fetch()) {
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
class BuildData {
|
class BuildData {
|
||||||
static const String name = "ServerBox";
|
static const String name = "ServerBox";
|
||||||
static const int build = 1018;
|
static const int build = 1021;
|
||||||
static const int script = 51;
|
static const int script = 53;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -340,5 +340,6 @@
|
|||||||
"willTakEeffectImmediately": "Wird sofort angewendet",
|
"willTakEeffectImmediately": "Wird sofort angewendet",
|
||||||
"wolTip": "Nach der Konfiguration von WOL (Wake-on-LAN) wird jedes Mal, wenn der Server verbunden wird, eine WOL-Anfrage gesendet.",
|
"wolTip": "Nach der Konfiguration von WOL (Wake-on-LAN) wird jedes Mal, wenn der Server verbunden wird, eine WOL-Anfrage gesendet.",
|
||||||
"write": "Schreiben",
|
"write": "Schreiben",
|
||||||
"writeScriptFailTip": "Das Schreiben des Skripts ist fehlgeschlagen, möglicherweise aufgrund fehlender Berechtigungen oder das Verzeichnis existiert nicht."
|
"writeScriptFailTip": "Das Schreiben des Skripts ist fehlgeschlagen, möglicherweise aufgrund fehlender Berechtigungen oder das Verzeichnis existiert nicht.",
|
||||||
|
"writeScriptTip": "Nach der Verbindung mit dem Server wird ein Skript in ~/.config/server_box geschrieben, um den Systemstatus zu überwachen. Sie können den Skriptinhalt überprüfen."
|
||||||
}
|
}
|
||||||
@@ -340,5 +340,6 @@
|
|||||||
"willTakEeffectImmediately": "Will take effect immediately",
|
"willTakEeffectImmediately": "Will take effect immediately",
|
||||||
"wolTip": "After configuring WOL (Wake-on-LAN), a WOL request is sent each time the server is connected.",
|
"wolTip": "After configuring WOL (Wake-on-LAN), a WOL request is sent each time the server is connected.",
|
||||||
"write": "Write",
|
"write": "Write",
|
||||||
"writeScriptFailTip": "Writing to the script failed, possibly due to lack of permissions or the directory does not exist."
|
"writeScriptFailTip": "Writing to the script failed, possibly due to lack of permissions or the directory does not exist.",
|
||||||
|
"writeScriptTip": "After connecting to the server, a script will be written to ~/.config/server_box to monitor the system status. You can review the script content."
|
||||||
}
|
}
|
||||||
@@ -340,5 +340,6 @@
|
|||||||
"willTakEeffectImmediately": "Los cambios tendrán efecto inmediatamente",
|
"willTakEeffectImmediately": "Los cambios tendrán efecto inmediatamente",
|
||||||
"wolTip": "Después de configurar WOL (Wake-on-LAN), se envía una solicitud de WOL cada vez que se conecta el servidor.",
|
"wolTip": "Después de configurar WOL (Wake-on-LAN), se envía una solicitud de WOL cada vez que se conecta el servidor.",
|
||||||
"write": "Escribir",
|
"write": "Escribir",
|
||||||
"writeScriptFailTip": "La escritura en el script falló, posiblemente por falta de permisos o porque el directorio no existe."
|
"writeScriptFailTip": "La escritura en el script falló, posiblemente por falta de permisos o porque el directorio no existe.",
|
||||||
|
"writeScriptTip": "Después de conectarse al servidor, se escribirá un script en ~/.config/server_box para monitorear el estado del sistema. Puedes revisar el contenido del script."
|
||||||
}
|
}
|
||||||
@@ -340,5 +340,6 @@
|
|||||||
"willTakEeffectImmediately": "Prendra effet immédiatement",
|
"willTakEeffectImmediately": "Prendra effet immédiatement",
|
||||||
"wolTip": "Après avoir configuré le WOL (Wake-on-LAN), une requête WOL est envoyée chaque fois que le serveur est connecté.",
|
"wolTip": "Après avoir configuré le WOL (Wake-on-LAN), une requête WOL est envoyée chaque fois que le serveur est connecté.",
|
||||||
"write": "Écrire",
|
"write": "Écrire",
|
||||||
"writeScriptFailTip": "Échec de l'écriture dans le script, probablement en raison d'un manque de permissions ou que le répertoire n'existe pas."
|
"writeScriptFailTip": "Échec de l'écriture dans le script, probablement en raison d'un manque de permissions ou que le répertoire n'existe pas.",
|
||||||
|
"writeScriptTip": "Après la connexion au serveur, un script sera écrit dans ~/.config/server_box pour surveiller l’état du système. Vous pouvez examiner le contenu du script."
|
||||||
}
|
}
|
||||||
@@ -340,5 +340,6 @@
|
|||||||
"willTakEeffectImmediately": "Akan segera berlaku",
|
"willTakEeffectImmediately": "Akan segera berlaku",
|
||||||
"wolTip": "Setelah mengonfigurasi WOL (Wake-on-LAN), permintaan WOL dikirim setiap kali server terhubung.",
|
"wolTip": "Setelah mengonfigurasi WOL (Wake-on-LAN), permintaan WOL dikirim setiap kali server terhubung.",
|
||||||
"write": "Tulis",
|
"write": "Tulis",
|
||||||
"writeScriptFailTip": "Penulisan ke skrip gagal, mungkin karena tidak ada izin atau direktori tidak ada."
|
"writeScriptFailTip": "Penulisan ke skrip gagal, mungkin karena tidak ada izin atau direktori tidak ada.",
|
||||||
|
"writeScriptTip": "Setelah terhubung ke server, sebuah skrip akan ditulis ke ~/.config/server_box untuk memantau status sistem. Anda dapat meninjau konten skrip tersebut."
|
||||||
}
|
}
|
||||||
@@ -340,5 +340,6 @@
|
|||||||
"willTakEeffectImmediately": "変更は即座に有効になります",
|
"willTakEeffectImmediately": "変更は即座に有効になります",
|
||||||
"wolTip": "WOL(Wake-on-LAN)を設定した後、サーバーに接続するたびにWOLリクエストが送信されます。",
|
"wolTip": "WOL(Wake-on-LAN)を設定した後、サーバーに接続するたびにWOLリクエストが送信されます。",
|
||||||
"write": "書き込み",
|
"write": "書き込み",
|
||||||
"writeScriptFailTip": "スクリプトの書き込みに失敗しました。権限がないかディレクトリが存在しない可能性があります。"
|
"writeScriptFailTip": "スクリプトの書き込みに失敗しました。権限がないかディレクトリが存在しない可能性があります。",
|
||||||
|
"writeScriptTip": "サーバーに接続すると、システムの状態を監視するためのスクリプトが ~/.config/server_box に書き込まれます。スクリプトの内容を確認できます。"
|
||||||
}
|
}
|
||||||
@@ -340,5 +340,6 @@
|
|||||||
"willTakEeffectImmediately": "Zal onmiddellijk van kracht worden",
|
"willTakEeffectImmediately": "Zal onmiddellijk van kracht worden",
|
||||||
"wolTip": "Na het configureren van WOL (Wake-on-LAN), wordt elke keer dat de server wordt verbonden een WOL-verzoek verzonden.",
|
"wolTip": "Na het configureren van WOL (Wake-on-LAN), wordt elke keer dat de server wordt verbonden een WOL-verzoek verzonden.",
|
||||||
"write": "Schrijven",
|
"write": "Schrijven",
|
||||||
"writeScriptFailTip": "Het schrijven naar het script is mislukt, mogelijk door gebrek aan rechten of omdat de map niet bestaat."
|
"writeScriptFailTip": "Het schrijven naar het script is mislukt, mogelijk door gebrek aan rechten of omdat de map niet bestaat.",
|
||||||
|
"writeScriptTip": "Na het verbinden met de server wordt een script geschreven naar ~/.config/server_box om de systeemstatus te monitoren. U kunt de inhoud van het script controleren."
|
||||||
}
|
}
|
||||||
@@ -340,5 +340,6 @@
|
|||||||
"willTakEeffectImmediately": "As alterações serão aplicadas imediatamente",
|
"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.",
|
"wolTip": "Após configurar o WOL (Wake-on-LAN), um pedido de WOL é enviado cada vez que o servidor é conectado.",
|
||||||
"write": "Escrita",
|
"write": "Escrita",
|
||||||
"writeScriptFailTip": "Falha ao escrever no script, possivelmente devido à falta de permissões ou o diretório não existe."
|
"writeScriptFailTip": "Falha ao escrever no script, possivelmente devido à falta de permissões ou o diretório não existe.",
|
||||||
|
"writeScriptTip": "Após conectar ao servidor, um script será escrito em ~/.config/server_box para monitorar o status do sistema. Você pode revisar o conteúdo do script."
|
||||||
}
|
}
|
||||||
@@ -340,5 +340,6 @@
|
|||||||
"willTakEeffectImmediately": "Изменения вступят в силу немедленно",
|
"willTakEeffectImmediately": "Изменения вступят в силу немедленно",
|
||||||
"wolTip": "После настройки WOL (Wake-on-LAN) при каждом подключении к серверу отправляется запрос WOL.",
|
"wolTip": "После настройки WOL (Wake-on-LAN) при каждом подключении к серверу отправляется запрос WOL.",
|
||||||
"write": "запись",
|
"write": "запись",
|
||||||
"writeScriptFailTip": "Запись в скрипт не удалась, возможно, из-за отсутствия прав или директории не существует."
|
"writeScriptFailTip": "Запись в скрипт не удалась, возможно, из-за отсутствия прав или директории не существует.",
|
||||||
|
"writeScriptTip": "После подключения к серверу скрипт будет записан в ~/.config/server_box для мониторинга состояния системы. Вы можете проверить содержимое скрипта."
|
||||||
}
|
}
|
||||||
@@ -340,5 +340,6 @@
|
|||||||
"willTakEeffectImmediately": "更改将会立即生效",
|
"willTakEeffectImmediately": "更改将会立即生效",
|
||||||
"wolTip": "在配置 WOL 后,每次连接服务器都会先发送一次 WOL 请求",
|
"wolTip": "在配置 WOL 后,每次连接服务器都会先发送一次 WOL 请求",
|
||||||
"write": "写",
|
"write": "写",
|
||||||
"writeScriptFailTip": "写入脚本失败,可能是没有权限/目录不存在等"
|
"writeScriptFailTip": "写入脚本失败,可能是没有权限/目录不存在等",
|
||||||
|
"writeScriptTip": "在连接服务器后,会向 ~/.config/server_box 写入脚本来监测系统状态,你可以审查脚本内容。"
|
||||||
}
|
}
|
||||||
@@ -340,5 +340,6 @@
|
|||||||
"willTakEeffectImmediately": "更改將會立即生效",
|
"willTakEeffectImmediately": "更改將會立即生效",
|
||||||
"wolTip": "在配置 WOL(網絡喚醒)後,每次連接伺服器都會先發送一次 WOL 請求。",
|
"wolTip": "在配置 WOL(網絡喚醒)後,每次連接伺服器都會先發送一次 WOL 請求。",
|
||||||
"write": "写",
|
"write": "写",
|
||||||
"writeScriptFailTip": "寫入腳本失敗,可能是沒有權限/目錄不存在等。"
|
"writeScriptFailTip": "寫入腳本失敗,可能是沒有權限/目錄不存在等。",
|
||||||
|
"writeScriptTip": "連接到伺服器後,將會在 ~/.config/server_box 中寫入一個腳本來監測系統狀態。你可以審查腳本內容。"
|
||||||
}
|
}
|
||||||
@@ -9,7 +9,6 @@ import 'package:flutter_displaymode/flutter_displaymode.dart';
|
|||||||
import 'package:hive_flutter/hive_flutter.dart';
|
import 'package:hive_flutter/hive_flutter.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
import 'package:server_box/app.dart';
|
import 'package:server_box/app.dart';
|
||||||
import 'package:server_box/core/utils/sync/icloud.dart';
|
import 'package:server_box/core/utils/sync/icloud.dart';
|
||||||
import 'package:server_box/core/utils/sync/webdav.dart';
|
import 'package:server_box/core/utils/sync/webdav.dart';
|
||||||
@@ -95,11 +94,7 @@ Future<void> _initData() async {
|
|||||||
Hive.registerAdapter(ServerCustomAdapter()); // 7
|
Hive.registerAdapter(ServerCustomAdapter()); // 7
|
||||||
Hive.registerAdapter(WakeOnLanCfgAdapter()); // 8
|
Hive.registerAdapter(WakeOnLanCfgAdapter()); // 8
|
||||||
|
|
||||||
try {
|
await SharedPref.init(); // Call this before accessing any store
|
||||||
/// Apps' data on other platforms are stored in a container that prevents
|
|
||||||
/// access by other apps. Therefore, there is no need to encrypt the data.
|
|
||||||
if (isLinux || isWindows) await SecureStore.init();
|
|
||||||
} catch (_) {}
|
|
||||||
|
|
||||||
await Stores.setting.init();
|
await Stores.setting.init();
|
||||||
await Stores.server.init();
|
await Stores.server.init();
|
||||||
@@ -127,8 +122,6 @@ void _setupDebug() {
|
|||||||
|
|
||||||
void _doPlatformRelated() async {
|
void _doPlatformRelated() async {
|
||||||
if (isAndroid) {
|
if (isAndroid) {
|
||||||
// SharedPreferences is only used on Android for saving home widgets settings.
|
|
||||||
SharedPreferences.setPrefix('');
|
|
||||||
// try switch to highest refresh rate
|
// try switch to highest refresh rate
|
||||||
FlutterDisplayMode.setHighRefreshRate();
|
FlutterDisplayMode.setHighRefreshRate();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -305,6 +305,8 @@ class BackupPage extends StatelessWidget {
|
|||||||
final url = TextEditingController(text: Stores.setting.webdavUrl.fetch());
|
final url = TextEditingController(text: Stores.setting.webdavUrl.fetch());
|
||||||
final user = TextEditingController(text: Stores.setting.webdavUser.fetch());
|
final user = TextEditingController(text: Stores.setting.webdavUser.fetch());
|
||||||
final pwd = TextEditingController(text: Stores.setting.webdavPwd.fetch());
|
final pwd = TextEditingController(text: Stores.setting.webdavPwd.fetch());
|
||||||
|
final nodeUser = FocusNode();
|
||||||
|
final nodePwd = FocusNode();
|
||||||
final result = await context.showRoundDialog<bool>(
|
final result = await context.showRoundDialog<bool>(
|
||||||
title: 'WebDAV',
|
title: 'WebDAV',
|
||||||
child: Column(
|
child: Column(
|
||||||
@@ -314,14 +316,19 @@ class BackupPage extends StatelessWidget {
|
|||||||
label: 'URL',
|
label: 'URL',
|
||||||
hint: 'https://example.com/webdav/',
|
hint: 'https://example.com/webdav/',
|
||||||
controller: url,
|
controller: url,
|
||||||
|
onSubmitted: (p0) => FocusScope.of(context).requestFocus(nodeUser),
|
||||||
),
|
),
|
||||||
Input(
|
Input(
|
||||||
label: l10n.user,
|
label: l10n.user,
|
||||||
controller: user,
|
controller: user,
|
||||||
|
node: nodeUser,
|
||||||
|
onSubmitted: (p0) => FocusScope.of(context).requestFocus(nodePwd),
|
||||||
),
|
),
|
||||||
Input(
|
Input(
|
||||||
label: l10n.pwd,
|
label: l10n.pwd,
|
||||||
controller: pwd,
|
controller: pwd,
|
||||||
|
node: nodePwd,
|
||||||
|
onSubmitted: (_) => context.pop(true),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -118,32 +118,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
|
|||||||
Widget _buildFAB() {
|
Widget _buildFAB() {
|
||||||
return FloatingActionButton(
|
return FloatingActionButton(
|
||||||
tooltip: l10n.save,
|
tooltip: l10n.save,
|
||||||
onPressed: () async {
|
onPressed: _onTapSave,
|
||||||
final name = _nameController.text;
|
|
||||||
final key = _standardizeLineSeparators(_keyController.text.trim());
|
|
||||||
final pwd = _pwdController.text;
|
|
||||||
if (name.isEmpty || key.isEmpty) {
|
|
||||||
context.showSnackBar(l10n.fieldMustNotEmpty);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
FocusScope.of(context).unfocus();
|
|
||||||
_loading.value = UIs.centerSizedLoading;
|
|
||||||
try {
|
|
||||||
final decrypted = await Computer.shared.start(decyptPem, [key, pwd]);
|
|
||||||
final pki = PrivateKeyInfo(id: name, key: decrypted);
|
|
||||||
if (widget.pki != null) {
|
|
||||||
Pros.key.update(widget.pki!, pki);
|
|
||||||
} else {
|
|
||||||
Pros.key.add(pki);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
context.showSnackBar(e.toString());
|
|
||||||
rethrow;
|
|
||||||
} finally {
|
|
||||||
_loading.value = null;
|
|
||||||
}
|
|
||||||
context.pop();
|
|
||||||
},
|
|
||||||
child: const Icon(Icons.save),
|
child: const Icon(Icons.save),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -206,6 +181,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
|
|||||||
obscureText: true,
|
obscureText: true,
|
||||||
label: l10n.pwd,
|
label: l10n.pwd,
|
||||||
icon: Icons.password,
|
icon: Icons.password,
|
||||||
|
onSubmitted: (_) => _onTapSave(),
|
||||||
),
|
),
|
||||||
SizedBox(height: MediaQuery.of(context).size.height * 0.1),
|
SizedBox(height: MediaQuery.of(context).size.height * 0.1),
|
||||||
ValBuilder(
|
ValBuilder(
|
||||||
@@ -215,4 +191,31 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onTapSave() async {
|
||||||
|
final name = _nameController.text;
|
||||||
|
final key = _standardizeLineSeparators(_keyController.text.trim());
|
||||||
|
final pwd = _pwdController.text;
|
||||||
|
if (name.isEmpty || key.isEmpty) {
|
||||||
|
context.showSnackBar(l10n.fieldMustNotEmpty);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FocusScope.of(context).unfocus();
|
||||||
|
_loading.value = UIs.centerSizedLoading;
|
||||||
|
try {
|
||||||
|
final decrypted = await Computer.shared.start(decyptPem, [key, pwd]);
|
||||||
|
final pki = PrivateKeyInfo(id: name, key: decrypted);
|
||||||
|
if (widget.pki != null) {
|
||||||
|
Pros.key.update(widget.pki!, pki);
|
||||||
|
} else {
|
||||||
|
Pros.key.add(pki);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
context.showSnackBar(e.toString());
|
||||||
|
rethrow;
|
||||||
|
} finally {
|
||||||
|
_loading.value = null;
|
||||||
|
}
|
||||||
|
context.pop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class _ProcessPageState extends State<ProcessPage> {
|
|||||||
Future<void> _refresh() async {
|
Future<void> _refresh() async {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
final result =
|
final result =
|
||||||
await _client?.run(ShellFunc.process.exec(widget.spi.id)).string;
|
await _client?.run(ShellFunc.process.exec).string;
|
||||||
if (result == null || result.isEmpty) {
|
if (result == null || result.isEmpty) {
|
||||||
context.showSnackBar(l10n.noResult);
|
context.showSnackBar(l10n.noResult);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -174,6 +174,7 @@ class _ServerEditPageState extends State<ServerEditPage> {
|
|||||||
|
|
||||||
Widget _buildForm() {
|
Widget _buildForm() {
|
||||||
final children = [
|
final children = [
|
||||||
|
_buildWriteScriptTip(),
|
||||||
Input(
|
Input(
|
||||||
autoFocus: true,
|
autoFocus: true,
|
||||||
controller: _nameController,
|
controller: _nameController,
|
||||||
@@ -638,4 +639,19 @@ class _ServerEditPageState extends State<ServerEditPage> {
|
|||||||
|
|
||||||
context.pop();
|
context.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildWriteScriptTip() {
|
||||||
|
return ListTile(
|
||||||
|
leading: const Icon(Icons.tips_and_updates).paddingOnly(left: 13),
|
||||||
|
title: Text(l10n.attention),
|
||||||
|
onTap: () {
|
||||||
|
context.showRoundDialog(
|
||||||
|
title: l10n.attention,
|
||||||
|
child: SimpleMarkdown(data: l10n.writeScriptTip),
|
||||||
|
actions: Btns.oks(onTap: () => context.pop(true)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
trailing: const Icon(Icons.keyboard_arrow_right),
|
||||||
|
).cardx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -356,7 +356,7 @@ class _ServerPageState extends State<ServerPage>
|
|||||||
Stores.setting.showSuspendTip.put(false);
|
Stores.setting.showSuspendTip.put(false);
|
||||||
}
|
}
|
||||||
srv.client?.execWithPwd(
|
srv.client?.execWithPwd(
|
||||||
ShellFunc.suspend.exec(srv.id),
|
ShellFunc.suspend.exec,
|
||||||
context: context,
|
context: context,
|
||||||
id: srv.id,
|
id: srv.id,
|
||||||
);
|
);
|
||||||
@@ -370,7 +370,7 @@ class _ServerPageState extends State<ServerPage>
|
|||||||
IconTextBtn(
|
IconTextBtn(
|
||||||
onPressed: () => _askFor(
|
onPressed: () => _askFor(
|
||||||
func: () => srv.client?.execWithPwd(
|
func: () => srv.client?.execWithPwd(
|
||||||
ShellFunc.shutdown.exec(srv.id),
|
ShellFunc.shutdown.exec,
|
||||||
context: context,
|
context: context,
|
||||||
id: srv.id,
|
id: srv.id,
|
||||||
),
|
),
|
||||||
@@ -383,7 +383,7 @@ class _ServerPageState extends State<ServerPage>
|
|||||||
IconTextBtn(
|
IconTextBtn(
|
||||||
onPressed: () => _askFor(
|
onPressed: () => _askFor(
|
||||||
func: () => srv.client?.execWithPwd(
|
func: () => srv.client?.execWithPwd(
|
||||||
ShellFunc.reboot.exec(srv.id),
|
ShellFunc.reboot.exec,
|
||||||
context: context,
|
context: context,
|
||||||
id: srv.id,
|
id: srv.id,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -581,21 +581,8 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
|||||||
void _mkdir() {
|
void _mkdir() {
|
||||||
context.pop();
|
context.pop();
|
||||||
final textController = TextEditingController();
|
final textController = TextEditingController();
|
||||||
context.showRoundDialog(
|
|
||||||
title: l10n.createFolder,
|
void onSubmitted() async {
|
||||||
child: Input(
|
|
||||||
autoFocus: true,
|
|
||||||
icon: Icons.folder,
|
|
||||||
controller: textController,
|
|
||||||
label: l10n.name,
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () => context.pop(),
|
|
||||||
child: Text(l10n.cancel),
|
|
||||||
),
|
|
||||||
TextButton(
|
|
||||||
onPressed: () async {
|
|
||||||
if (textController.text.isEmpty) {
|
if (textController.text.isEmpty) {
|
||||||
context.showRoundDialog(
|
context.showRoundDialog(
|
||||||
child: Text(l10n.fieldMustNotEmpty),
|
child: Text(l10n.fieldMustNotEmpty),
|
||||||
@@ -621,7 +608,24 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
|||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
context.showErrDialog(e: e, s: s, operation: l10n.createFolder);
|
context.showErrDialog(e: e, s: s, operation: l10n.createFolder);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
|
context.showRoundDialog(
|
||||||
|
title: l10n.createFolder,
|
||||||
|
child: Input(
|
||||||
|
autoFocus: true,
|
||||||
|
icon: Icons.folder,
|
||||||
|
controller: textController,
|
||||||
|
label: l10n.name,
|
||||||
|
onSubmitted: (_) => onSubmitted(),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => context.pop(),
|
||||||
|
child: Text(l10n.cancel),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: onSubmitted,
|
||||||
child: Text(l10n.ok, style: UIs.textRed),
|
child: Text(l10n.ok, style: UIs.textRed),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -631,17 +635,8 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
|||||||
void _newFile() {
|
void _newFile() {
|
||||||
context.pop();
|
context.pop();
|
||||||
final textController = TextEditingController();
|
final textController = TextEditingController();
|
||||||
context.showRoundDialog(
|
|
||||||
title: l10n.createFile,
|
void onSubmitted() async {
|
||||||
child: Input(
|
|
||||||
autoFocus: true,
|
|
||||||
icon: Icons.insert_drive_file,
|
|
||||||
controller: textController,
|
|
||||||
label: l10n.name,
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () async {
|
|
||||||
if (textController.text.isEmpty) {
|
if (textController.text.isEmpty) {
|
||||||
context.showRoundDialog(
|
context.showRoundDialog(
|
||||||
title: l10n.attention,
|
title: l10n.attention,
|
||||||
@@ -668,7 +663,20 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
|||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
context.showErrDialog(e: e, s: s, operation: l10n.createFile);
|
context.showErrDialog(e: e, s: s, operation: l10n.createFile);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
|
context.showRoundDialog(
|
||||||
|
title: l10n.createFile,
|
||||||
|
child: Input(
|
||||||
|
autoFocus: true,
|
||||||
|
icon: Icons.insert_drive_file,
|
||||||
|
controller: textController,
|
||||||
|
label: l10n.name,
|
||||||
|
onSubmitted: (_) => onSubmitted(),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: onSubmitted,
|
||||||
child: Text(l10n.ok, style: UIs.textRed),
|
child: Text(l10n.ok, style: UIs.textRed),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -678,18 +686,8 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
|||||||
void _rename(SftpName file) {
|
void _rename(SftpName file) {
|
||||||
context.pop();
|
context.pop();
|
||||||
final textController = TextEditingController(text: file.filename);
|
final textController = TextEditingController(text: file.filename);
|
||||||
context.showRoundDialog(
|
|
||||||
title: l10n.rename,
|
void onSubmitted() async {
|
||||||
child: Input(
|
|
||||||
autoFocus: true,
|
|
||||||
icon: Icons.abc,
|
|
||||||
controller: textController,
|
|
||||||
label: l10n.name,
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(onPressed: () => context.pop(), child: Text(l10n.cancel)),
|
|
||||||
TextButton(
|
|
||||||
onPressed: () async {
|
|
||||||
if (textController.text.isEmpty) {
|
if (textController.text.isEmpty) {
|
||||||
context.showRoundDialog(
|
context.showRoundDialog(
|
||||||
title: l10n.attention,
|
title: l10n.attention,
|
||||||
@@ -716,7 +714,21 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
|||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
context.showErrDialog(e: e, s: s, operation: l10n.rename);
|
context.showErrDialog(e: e, s: s, operation: l10n.rename);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
|
context.showRoundDialog(
|
||||||
|
title: l10n.rename,
|
||||||
|
child: Input(
|
||||||
|
autoFocus: true,
|
||||||
|
icon: Icons.abc,
|
||||||
|
controller: textController,
|
||||||
|
label: l10n.name,
|
||||||
|
onSubmitted: (_) => onSubmitted(),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(onPressed: () => context.pop(), child: Text(l10n.cancel)),
|
||||||
|
TextButton(
|
||||||
|
onPressed: onSubmitted,
|
||||||
child: Text(l10n.rename, style: UIs.textRed),
|
child: Text(l10n.rename, style: UIs.textRed),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -471,7 +471,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1018;
|
CURRENT_PROJECT_VERSION = 1021;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = "Server Box";
|
INFOPLIST_KEY_CFBundleDisplayName = "Server Box";
|
||||||
@@ -481,7 +481,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||||
MARKETING_VERSION = 1.0.1018;
|
MARKETING_VERSION = 1.0.1021;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||||
PRODUCT_NAME = "Server Box";
|
PRODUCT_NAME = "Server Box";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@@ -608,7 +608,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1018;
|
CURRENT_PROJECT_VERSION = 1021;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = "Server Box";
|
INFOPLIST_KEY_CFBundleDisplayName = "Server Box";
|
||||||
@@ -618,7 +618,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||||
MARKETING_VERSION = 1.0.1018;
|
MARKETING_VERSION = 1.0.1021;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||||
PRODUCT_NAME = "Server Box";
|
PRODUCT_NAME = "Server Box";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@@ -638,7 +638,7 @@
|
|||||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application";
|
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application";
|
||||||
CODE_SIGN_STYLE = Manual;
|
CODE_SIGN_STYLE = Manual;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1018;
|
CURRENT_PROJECT_VERSION = 1021;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
"DEVELOPMENT_TEAM[sdk=macosx*]" = BA88US33G6;
|
"DEVELOPMENT_TEAM[sdk=macosx*]" = BA88US33G6;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@@ -649,7 +649,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||||
MARKETING_VERSION = 1.0.1018;
|
MARKETING_VERSION = 1.0.1021;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||||
PRODUCT_NAME = "Server Box";
|
PRODUCT_NAME = "Server Box";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
|||||||
@@ -385,8 +385,8 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: "v1.0.74"
|
ref: "v1.0.77"
|
||||||
resolved-ref: "42000d49fd62ee202a4b37d0a97c29f77c83d0d8"
|
resolved-ref: "57c4c0187673ea9c38b39889ac467be4a8bbddba"
|
||||||
url: "https://github.com/lppcg/fl_lib"
|
url: "https://github.com/lppcg/fl_lib"
|
||||||
source: git
|
source: git
|
||||||
version: "0.0.1"
|
version: "0.0.1"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: server_box
|
name: server_box
|
||||||
description: server status & toolbox app.
|
description: server status & toolbox app.
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
version: 1.0.1018+1018
|
version: 1.0.1021+1021
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.0.0"
|
sdk: ">=3.0.0"
|
||||||
@@ -61,11 +61,11 @@ dependencies:
|
|||||||
fl_lib:
|
fl_lib:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/lppcg/fl_lib
|
url: https://github.com/lppcg/fl_lib
|
||||||
ref: v1.0.74
|
ref: v1.0.77
|
||||||
|
|
||||||
dependency_overrides:
|
dependency_overrides:
|
||||||
# dartssh2:
|
# dartssh2:
|
||||||
# path: ../dartssh2
|
# path: ../dartssh2
|
||||||
# fl_lib:
|
# fl_lib:
|
||||||
# path: ../fl_lib
|
# path: ../fl_lib
|
||||||
# xterm:
|
# xterm:
|
||||||
|
|||||||
Reference in New Issue
Block a user