feat: use native ssh terminal on desktop

Implement #109
This commit is contained in:
lollipopkit
2023-08-07 16:27:00 +08:00
parent 2142ae3e1c
commit d37a1fbea7
3 changed files with 40 additions and 37 deletions

View File

@@ -43,8 +43,7 @@ class _ProcessPageState extends State<ProcessPage> {
showSnackBar(context, Text(_s.noClient)); showSnackBar(context, Text(_s.noClient));
return; return;
} }
_timer = _timer = Timer.periodic(const Duration(seconds: 3), (_) => _refresh());
Timer.periodic(const Duration(seconds: 3), (_) => _refresh());
} }
Future<void> _refresh() async { Future<void> _refresh() async {

View File

@@ -1,3 +1,5 @@
import 'dart:io' show File, Platform, Process;
import 'package:after_layout/after_layout.dart'; import 'package:after_layout/after_layout.dart';
import 'package:circle_chart/circle_chart.dart'; import 'package:circle_chart/circle_chart.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -15,6 +17,8 @@ import 'package:toolbox/view/widget/tag/picker.dart';
import 'package:toolbox/view/widget/tag/switcher.dart'; import 'package:toolbox/view/widget/tag/switcher.dart';
import '../../../core/route.dart'; import '../../../core/route.dart';
import '../../../core/utils/platform.dart';
import '../../../core/utils/server.dart';
import '../../../core/utils/ui.dart'; import '../../../core/utils/ui.dart';
import '../../../data/model/server/disk.dart'; import '../../../data/model/server/disk.dart';
import '../../../data/model/server/server.dart'; import '../../../data/model/server/server.dart';
@@ -225,7 +229,6 @@ class _ServerPageState extends State<ServerPage>
_buildTopRightText(ss, cs), _buildTopRightText(ss, cs),
width13, width13,
_buildSSHBtn(spi), _buildSSHBtn(spi),
// SizedBox(width: 5,),
_buildMoreBtn(spi), _buildMoreBtn(spi),
], ],
) )
@@ -271,12 +274,9 @@ class _ServerPageState extends State<ServerPage>
} }
Widget _buildSSHBtn(ServerPrivateInfo spi) { Widget _buildSSHBtn(ServerPrivateInfo spi) {
return IconButton( return GestureDetector(
icon: const Icon( child: const Icon(Icons.terminal, size: 21),
Icons.terminal, onTap: () => gotoSSH(spi),
size: 21,
),
onPressed: () => startSSH(spi, context),
); );
} }
@@ -447,6 +447,38 @@ class _ServerPageState extends State<ServerPage>
); );
} }
void gotoSSH(ServerPrivateInfo spi) {
// as a `Mobile first` app -> handle mobile first
if (!isDesktop) {
AppRoute(SSHPage(spi: spi), 'ssh page').go(context);
return;
}
List<String> extarArgs = [];
if (spi.pubKeyId != null) {
String path = "/tmp/.serverbox_pk_${spi.pubKeyId}";
File(path).openWrite().write(getPrivateKey(spi.pubKeyId!));
extarArgs += ["-i", path];
}
List<String> sshCommand = ["ssh", "${spi.user}@${spi.ip}"] + extarArgs;
switch (Platform.operatingSystem) {
case "windows":
Process.start("cmd", ["/c", "start"] + sshCommand);
return;
case "linux":
Process.start("x-terminal-emulator", ["-e"] + sshCommand);
return;
case "macos":
Process.start("osascript", [
"-e",
'tell application "Terminal" to do script "${sshCommand.join(" ")}"'
]);
return;
default:
AppRoute(SSHPage(spi: spi), 'ssh page').go(context);
return;
}
}
@override @override
bool get wantKeepAlive => true; bool get wantKeepAlive => true;

View File

@@ -1,4 +1,3 @@
import 'dart:io' show Process, File;
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
@@ -26,33 +25,6 @@ import '../../../data/store/setting.dart';
import '../../../locator.dart'; import '../../../locator.dart';
import '../storage/sftp.dart'; import '../storage/sftp.dart';
startSSH(ServerPrivateInfo spi, BuildContext context) {
if (isLinux || isMacOS) {
unawaited(() async {
List<String> extarArgs = [];
if (spi.pubKeyId != null) {
String path = "/tmp/.serverbox_pk_${spi.pubKeyId}";
File(path).openWrite().write(getPrivateKey(spi.pubKeyId!));
extarArgs += ["-i", path];
}
List<String> sshCommand = ["ssh", spi.user + "@" + spi.ip] + extarArgs;
if (isLinux) {
Process.start("x-terminal-emulator", ["-e"] + sshCommand);
return;
}
if (isMacOS) {
Process.start("osascript", [
"-e",
'tell application "Terminal" to do script "${sshCommand.join(" ")}"'
]);
return;
}
}());
return;
}
AppRoute(SSHPage(spi: spi), 'ssh page').go(context);
}
class SSHPage extends StatefulWidget { class SSHPage extends StatefulWidget {
final ServerPrivateInfo spi; final ServerPrivateInfo spi;
final String? initCmd; final String? initCmd;