opt. for ssh
This commit is contained in:
@@ -34,11 +34,14 @@ Especially thanks to <a href="https://github.com/TerminalStudio/dartssh2">dartss
|
|||||||
<img width="200px" src="screenshots/server.jpg">
|
<img width="200px" src="screenshots/server.jpg">
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<img width="200px" src="screenshots/server_detail.png">
|
<img width="200px" src="screenshots/detail.jpg">
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<img width="200px" src="screenshots/ssh.jpg">
|
<img width="200px" src="screenshots/ssh.jpg">
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<img width="200px" src="screenshots/apt.png">
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<table>
|
<table>
|
||||||
@@ -52,6 +55,9 @@ Especially thanks to <a href="https://github.com/TerminalStudio/dartssh2">dartss
|
|||||||
<td>
|
<td>
|
||||||
<img width="200px" src="screenshots/docker.jpg">
|
<img width="200px" src="screenshots/docker.jpg">
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<img width="200px" src="screenshots/convert.png">
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
class BuildData {
|
class BuildData {
|
||||||
static const String name = "ServerBox";
|
static const String name = "ServerBox";
|
||||||
static const int build = 191;
|
static const int build = 193;
|
||||||
static const String engine =
|
static const String engine =
|
||||||
"Flutter 3.7.0 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision b06b8b2710 (5 days ago) • 2023-01-23 16:55:55 -0800\nEngine • revision b24591ed32\nTools • Dart 2.19.0 • DevTools 2.20.1\n";
|
"Flutter 3.7.0 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision b06b8b2710 (5 days ago) • 2023-01-23 16:55:55 -0800\nEngine • revision b24591ed32\nTools • Dart 2.19.0 • DevTools 2.20.1\n";
|
||||||
static const String buildAt = "2023-01-28 22:51:04.087758";
|
static const String buildAt = "2023-01-28 23:51:19.423469";
|
||||||
static const int modifications = 3;
|
static const int modifications = 2;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,15 +177,6 @@ class _PkgManagePageState extends State<PkgManagePage>
|
|||||||
return ListView(
|
return ListView(
|
||||||
padding: const EdgeInsets.all(13),
|
padding: const EdgeInsets.all(13),
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(17),
|
|
||||||
child: UrlText(
|
|
||||||
text:
|
|
||||||
'${_s.experimentalFeature}\n${_s.reportBugsOnGithubIssue(issueUrl)}',
|
|
||||||
replace: 'Github Issue',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
_buildUpdatePanel(apt)
|
_buildUpdatePanel(apt)
|
||||||
].map((e) => RoundRectCard(e)).toList(),
|
].map((e) => RoundRectCard(e)).toList(),
|
||||||
);
|
);
|
||||||
@@ -203,10 +194,7 @@ class _PkgManagePageState extends State<PkgManagePage>
|
|||||||
subtitle: const Text('>_<', textAlign: TextAlign.center),
|
subtitle: const Text('>_<', textAlign: TextAlign.center),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return Column(
|
return ExpansionTile(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
ExpansionTile(
|
|
||||||
title: Text(_s.foundNUpdate(apt.upgradeable!.length)),
|
title: Text(_s.foundNUpdate(apt.upgradeable!.length)),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
apt.upgradeable!.map((e) => e.package).join(', '),
|
apt.upgradeable!.map((e) => e.package).join(', '),
|
||||||
@@ -221,32 +209,18 @@ class _PkgManagePageState extends State<PkgManagePage>
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
apt.upgrade();
|
apt.upgrade();
|
||||||
}),
|
}),
|
||||||
SizedBox(
|
...apt.upgradeable!
|
||||||
height: _media.size.height * 0.73,
|
|
||||||
child: ListView(
|
|
||||||
controller: _scrollController,
|
|
||||||
children: apt.upgradeable!
|
|
||||||
.map((e) => _buildUpdateItem(e, apt))
|
.map((e) => _buildUpdateItem(e, apt))
|
||||||
.toList(),
|
.toList()
|
||||||
),
|
|
||||||
)
|
|
||||||
]
|
]
|
||||||
: [
|
: [
|
||||||
SizedBox(
|
SingleChildScrollView(
|
||||||
height: _media.size.height * 0.7,
|
|
||||||
child: ConstrainedBox(
|
|
||||||
constraints: const BoxConstraints.expand(),
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
padding: const EdgeInsets.all(18),
|
padding: const EdgeInsets.all(18),
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
child: Text(apt.upgradeLog!),
|
child: Text(apt.upgradeLog!),
|
||||||
),
|
)
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
)
|
);
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildUpdateItem(UpgradePkgInfo info, PkgProvider apt) {
|
Widget _buildUpdateItem(UpgradePkgInfo info, PkgProvider apt) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:dartssh2/dartssh2.dart';
|
import 'package:dartssh2/dartssh2.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:toolbox/data/store/setting.dart';
|
import 'package:toolbox/data/store/setting.dart';
|
||||||
@@ -11,6 +12,7 @@ import '../../core/utils.dart';
|
|||||||
import '../../data/model/server/server_private_info.dart';
|
import '../../data/model/server/server_private_info.dart';
|
||||||
import '../../data/provider/server.dart';
|
import '../../data/provider/server.dart';
|
||||||
import '../../data/res/terminal_theme.dart';
|
import '../../data/res/terminal_theme.dart';
|
||||||
|
import '../../data/store/private_key.dart';
|
||||||
import '../../locator.dart';
|
import '../../locator.dart';
|
||||||
|
|
||||||
class SSHPage extends StatefulWidget {
|
class SSHPage extends StatefulWidget {
|
||||||
@@ -23,7 +25,7 @@ class SSHPage extends StatefulWidget {
|
|||||||
|
|
||||||
class _SSHPageState extends State<SSHPage> {
|
class _SSHPageState extends State<SSHPage> {
|
||||||
late final terminal = Terminal(inputHandler: keyboard);
|
late final terminal = Terminal(inputHandler: keyboard);
|
||||||
late final SSHSession session;
|
late final SSHClient client;
|
||||||
final keyboard = VirtualKeyboard(defaultInputHandler);
|
final keyboard = VirtualKeyboard(defaultInputHandler);
|
||||||
late double _screenWidth;
|
late double _screenWidth;
|
||||||
|
|
||||||
@@ -44,23 +46,14 @@ class _SSHPageState extends State<SSHPage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
session.close();
|
client.close();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> initTerminal() async {
|
Future<void> initTerminal() async {
|
||||||
terminal.write('Connecting...\r\n');
|
terminal.write('Connecting...\r\n');
|
||||||
|
|
||||||
final client = locator<ServerProvider>()
|
client = await genClient(widget.spi);
|
||||||
.servers
|
|
||||||
.where((e) => e.spi.id == widget.spi.id)
|
|
||||||
.first
|
|
||||||
.client;
|
|
||||||
if (client == null) {
|
|
||||||
terminal.write('Failed to connect\r\n');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
terminal.write('Connected\r\n');
|
terminal.write('Connected\r\n');
|
||||||
|
|
||||||
final wxh = locator<SettingStore>().sshTermSize.fetch()!;
|
final wxh = locator<SettingStore>().sshTermSize.fetch()!;
|
||||||
@@ -69,7 +62,7 @@ class _SSHPageState extends State<SSHPage> {
|
|||||||
final h = int.parse(split.last);
|
final h = int.parse(split.last);
|
||||||
terminal.resize(w, h);
|
terminal.resize(w, h);
|
||||||
|
|
||||||
session = await client.shell(
|
final session = await client.shell(
|
||||||
pty: SSHPtyConfig(
|
pty: SSHPtyConfig(
|
||||||
width: terminal.viewWidth,
|
width: terminal.viewWidth,
|
||||||
height: terminal.viewHeight,
|
height: terminal.viewHeight,
|
||||||
@@ -191,6 +184,23 @@ class _SSHPageState extends State<SSHPage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<SSHClient> genClient(ServerPrivateInfo spi) async {
|
||||||
|
final socket = await SSHSocket.connect(spi.ip, spi.port);
|
||||||
|
if (spi.pubKeyId == null) {
|
||||||
|
return SSHClient(
|
||||||
|
socket,
|
||||||
|
username: spi.user,
|
||||||
|
onPasswordRequest: () => spi.pwd,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
final key = locator<PrivateKeyStore>().get(spi.pubKeyId!);
|
||||||
|
return SSHClient(
|
||||||
|
socket,
|
||||||
|
username: spi.user,
|
||||||
|
identities: await compute(loadIndentity, key.privateKey),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
class VirtualKey {
|
class VirtualKey {
|
||||||
final TerminalKey key;
|
final TerminalKey key;
|
||||||
final String text;
|
final String text;
|
||||||
|
|||||||
BIN
screenshots/detail.jpg
Normal file
BIN
screenshots/detail.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 181 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 183 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 228 KiB After Width: | Height: | Size: 224 KiB |
Reference in New Issue
Block a user