opt.: ssh tab

This commit is contained in:
lollipopkit
2023-11-12 17:09:43 +08:00
parent 790812901d
commit 55ba013977
13 changed files with 110 additions and 45 deletions

View File

@@ -530,6 +530,12 @@ abstract class S {
/// **'Extra args'**
String get extraArgs;
/// No description provided for @fabOpenSSHSession.
///
/// In en, this message translates to:
/// **'Click the FAB to open a session'**
String get fabOpenSSHSession;
/// No description provided for @failed.
///
/// In en, this message translates to:

View File

@@ -230,6 +230,9 @@ class SDe extends S {
@override
String get extraArgs => 'Extra args';
@override
String get fabOpenSSHSession => 'Klicken Sie auf die FAB, um eine Sitzung zu öffnen';
@override
String get failed => 'Failed';

View File

@@ -230,6 +230,9 @@ class SEn extends S {
@override
String get extraArgs => 'Extra args';
@override
String get fabOpenSSHSession => 'Click the FAB to open a session';
@override
String get failed => 'Failed';

View File

@@ -230,6 +230,9 @@ class SId extends S {
@override
String get extraArgs => 'Args ekstra';
@override
String get fabOpenSSHSession => 'Klik FAB untuk membuka sesi';
@override
String get failed => 'Gagal';

View File

@@ -230,6 +230,9 @@ class SZh extends S {
@override
String get extraArgs => '额外参数';
@override
String get fabOpenSSHSession => '点击右下FAB来开启新的SSH终端';
@override
String get failed => '失败';
@@ -1019,6 +1022,9 @@ class SZhTw extends SZh {
@override
String get extraArgs => '額外參數';
@override
String get fabOpenSSHSession => '點擊右下FAB來開啟新的SSH終端';
@override
String get failed => '失敗';

View File

@@ -16,7 +16,12 @@ class Server implements TagPickable {
SSHClient? client;
ServerState state;
Server(this.spi, this.status, this.client, this.state);
Server(
this.spi,
this.status,
this.state, {
this.client,
});
@override
bool containsTag(String tag) {

View File

@@ -72,6 +72,7 @@
"experimentalFeature": "Experimentelles Feature",
"export": "Export",
"extraArgs": "Extra args",
"fabOpenSSHSession": "Klicken Sie auf die FAB, um eine Sitzung zu öffnen",
"failed": "Failed",
"feedback": "Feedback",
"feedbackOnGithub": "Wenn du Fragen hast, stelle diese bitte auf Github.",

View File

@@ -72,6 +72,7 @@
"experimentalFeature": "Experimental feature",
"export": "Export",
"extraArgs": "Extra args",
"fabOpenSSHSession": "Click the FAB to open a session",
"failed": "Failed",
"feedback": "Feedback",
"feedbackOnGithub": "If you have any questions, please feedback on Github.",

View File

@@ -72,6 +72,7 @@
"experimentalFeature": "Fitur eksperimental",
"export": "Ekspor",
"extraArgs": "Args ekstra",
"fabOpenSSHSession": "Klik FAB untuk membuka sesi",
"failed": "Gagal",
"feedback": "Masukan",
"feedbackOnGithub": "Jika Anda memiliki pertanyaan, silakan umpan balik tentang GitHub.",

View File

@@ -72,6 +72,7 @@
"experimentalFeature": "实验性功能",
"export": "导出",
"extraArgs": "额外参数",
"fabOpenSSHSession": "点击右下FAB来开启新的SSH终端",
"failed": "失败",
"feedback": "反馈",
"feedbackOnGithub": "如果你有任何问题请在GitHub反馈",

View File

@@ -72,6 +72,7 @@
"experimentalFeature": "實驗性功能",
"export": "導出",
"extraArgs": "額外參數",
"fabOpenSSHSession": "點擊右下FAB來開啟新的SSH終端",
"failed": "失敗",
"feedback": "反饋",
"feedbackOnGithub": "如果你有任何問題請在GitHub反饋",

View File

@@ -1,7 +1,10 @@
import 'package:flutter/material.dart';
import 'package:toolbox/core/extension/context/common.dart';
import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/extension/context/locale.dart';
import 'package:toolbox/data/model/server/server.dart';
import 'package:toolbox/data/res/provider.dart';
import 'package:toolbox/data/res/ui.dart';
import 'package:toolbox/view/page/ssh/page.dart';
class SSHTabPage extends StatefulWidget {
@@ -13,7 +16,9 @@ class SSHTabPage extends StatefulWidget {
class _SSHTabPageState extends State<SSHTabPage>
with TickerProviderStateMixin, AutomaticKeepAliveClientMixin {
final _tabIds = <String, SSHPage>{};
late final _tabIds = <String, Widget>{
l10n.add: _addPage,
};
final _tabKeys = <String, GlobalKey>{};
late var _tabController = TabController(
length: _tabIds.length,
@@ -30,22 +35,42 @@ class _SSHTabPageState extends State<SSHTabPage>
isScrollable: true,
),
body: _buildBody(),
floatingActionButton: _buildFAB(),
);
}
Widget _buildTabItem(String e) {
if (e == l10n.add) {
return Tab(child: Text(e));
}
return Tab(
child: Row(
children: [
Text(e),
IconButton(
icon: const Icon(Icons.close),
padding: EdgeInsets.zero,
onPressed: () {
_tabKeys[e]?.currentState?.dispose();
UIs.width7,
InkWell(
borderRadius: BorderRadius.circular(17),
child: const Padding(padding: EdgeInsets.all(7), child: Icon(Icons.close, size: 17),),
onTap: () async {
final confirm = await context.showRoundDialog<bool>(
title: Text(l10n.attention),
child: Text('${l10n.close} SSH ${l10n.conn}($e) ?'),
actions: [
TextButton(
onPressed: () => context.pop(true),
child: Text(l10n.ok, style: UIs.textRed),
),
TextButton(
onPressed: () => context.pop(false),
child: Text(l10n.cancel),
),
],
);
if (confirm != true) {
return;
}
_tabIds.remove(e);
_refreshTabs();
//_tabKeys[e]?.currentState?.dispose();
},
),
],
@@ -53,45 +78,55 @@ class _SSHTabPageState extends State<SSHTabPage>
);
}
Widget _buildFAB() {
return FloatingActionButton(
onPressed: () async {
final spi = (await context.showPickDialog<Server>(
items: Pros.server.servers.toList(),
name: (e) => e.spi.name,
multi: false,
))
?.first
.spi;
if (spi == null) {
return;
}
final name = () {
if (_tabIds.containsKey(spi.name)) {
return '${spi.name}(${_tabIds.length + 1})';
}
return spi.name;
}();
final key = GlobalKey(debugLabel: 'sshTabPage_$name');
_tabIds[name] = SSHPage(
key: key,
spi: spi,
);
_tabKeys[name] = key;
_refreshTabs();
_tabController.animateTo(_tabIds.length - 1);
},
child: const Icon(Icons.add),
);
}
late final Widget _addPage = Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(77),
color: Colors.white10,
),
child: IconButton(
padding: const EdgeInsets.all(17),
onPressed: () async {
final spi = (await context.showPickDialog<Server>(
items: Pros.server.servers.toList(),
name: (e) => e.spi.name,
multi: false,
))
?.first
.spi;
if (spi == null) {
return;
}
final name = () {
if (_tabIds.containsKey(spi.name)) {
return '${spi.name}(${_tabIds.length + 1})';
}
return spi.name;
}();
final key = GlobalKey(debugLabel: 'sshTabPage_$name');
_tabIds[name] = SSHPage(
key: key,
spi: spi,
);
_tabKeys[name] = key;
_refreshTabs();
_tabController.animateTo(_tabIds.length - 1);
},
icon: const Icon(Icons.add),
),
),
UIs.height13,
Text(l10n.add),
],
),
);
Widget _buildBody() {
if (_tabIds.isEmpty) {
return const Center(
child: Text('Click the fab to open a session'),
);
}
return TabBarView(
physics: const NeverScrollableScrollPhysics(),
controller: _tabController,
children: _tabIds.values.toList(),
);

View File

@@ -21,7 +21,6 @@ class ChoiceChipX<T> extends StatelessWidget {
label: Text(label),
side: BorderSide.none,
selected: state.selected(value),
selectedColor: Theme.of(context).colorScheme.primary,
onSelected: state.onSelected(value),
),
);