opt.
- add help for ssh virt keys - rm unused lib
This commit is contained in:
@@ -17,7 +17,7 @@ class TryLimiter {
|
||||
return true;
|
||||
}
|
||||
|
||||
void resetTryTimes(String id) {
|
||||
void reset(String id) {
|
||||
_triedTimes[id] = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:xterm/core.dart';
|
||||
|
||||
@@ -17,7 +18,7 @@ enum VirtKey {
|
||||
@HiveField(4)
|
||||
end,
|
||||
@HiveField(5)
|
||||
file,
|
||||
sftp,
|
||||
@HiveField(6)
|
||||
snippet,
|
||||
@HiveField(7)
|
||||
@@ -31,7 +32,7 @@ enum VirtKey {
|
||||
@HiveField(11)
|
||||
right,
|
||||
@HiveField(12)
|
||||
paste,
|
||||
clipboard,
|
||||
@HiveField(13)
|
||||
ime,
|
||||
@HiveField(14)
|
||||
@@ -94,11 +95,11 @@ enum VirtKey {
|
||||
return Icons.arrow_downward;
|
||||
case VirtKey.right:
|
||||
return Icons.arrow_forward;
|
||||
case VirtKey.file:
|
||||
case VirtKey.sftp:
|
||||
return Icons.file_open;
|
||||
case VirtKey.snippet:
|
||||
return Icons.code;
|
||||
case VirtKey.paste:
|
||||
case VirtKey.clipboard:
|
||||
return Icons.paste;
|
||||
case VirtKey.ime:
|
||||
return Icons.keyboard_hide;
|
||||
@@ -112,12 +113,12 @@ enum VirtKey {
|
||||
// and make sure all [VirtualKeyFunc] are handled
|
||||
VirtualKeyFunc? get func {
|
||||
switch (this) {
|
||||
case VirtKey.file:
|
||||
case VirtKey.sftp:
|
||||
return VirtualKeyFunc.file;
|
||||
case VirtKey.snippet:
|
||||
return VirtualKeyFunc.snippet;
|
||||
case VirtKey.paste:
|
||||
return VirtualKeyFunc.paste;
|
||||
case VirtKey.clipboard:
|
||||
return VirtualKeyFunc.clipboard;
|
||||
case VirtKey.ime:
|
||||
return VirtualKeyFunc.toggleIME;
|
||||
default:
|
||||
@@ -146,6 +147,17 @@ enum VirtKey {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
String? help(S s) {
|
||||
switch (this) {
|
||||
case VirtKey.sftp:
|
||||
return s.virtKeyHelpSFTP;
|
||||
case VirtKey.clipboard:
|
||||
return s.virtKeyHelpClipboard;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum VirtualKeyFunc { toggleIME, backspace, copy, paste, snippet, file }
|
||||
enum VirtualKeyFunc { toggleIME, backspace, clipboard, snippet, file }
|
||||
|
||||
@@ -24,7 +24,7 @@ class VirtKeyAdapter extends TypeAdapter<VirtKey> {
|
||||
case 4:
|
||||
return VirtKey.end;
|
||||
case 5:
|
||||
return VirtKey.file;
|
||||
return VirtKey.sftp;
|
||||
case 6:
|
||||
return VirtKey.snippet;
|
||||
case 7:
|
||||
@@ -38,7 +38,7 @@ class VirtKeyAdapter extends TypeAdapter<VirtKey> {
|
||||
case 11:
|
||||
return VirtKey.right;
|
||||
case 12:
|
||||
return VirtKey.paste;
|
||||
return VirtKey.clipboard;
|
||||
case 13:
|
||||
return VirtKey.ime;
|
||||
case 14:
|
||||
@@ -68,7 +68,7 @@ class VirtKeyAdapter extends TypeAdapter<VirtKey> {
|
||||
case VirtKey.end:
|
||||
writer.writeByte(4);
|
||||
break;
|
||||
case VirtKey.file:
|
||||
case VirtKey.sftp:
|
||||
writer.writeByte(5);
|
||||
break;
|
||||
case VirtKey.snippet:
|
||||
@@ -89,7 +89,7 @@ class VirtKeyAdapter extends TypeAdapter<VirtKey> {
|
||||
case VirtKey.right:
|
||||
writer.writeByte(11);
|
||||
break;
|
||||
case VirtKey.paste:
|
||||
case VirtKey.clipboard:
|
||||
writer.writeByte(12);
|
||||
break;
|
||||
case VirtKey.ime:
|
||||
|
||||
@@ -101,7 +101,7 @@ class ServerProvider extends BusyProvider {
|
||||
await Future.wait(_servers.values.map((s) async {
|
||||
if (onlyFailed) {
|
||||
if (s.state != ServerState.failed) return;
|
||||
_limiter.resetTryTimes(s.spi.id);
|
||||
_limiter.reset(s.spi.id);
|
||||
}
|
||||
return await _getData(s.spi);
|
||||
}));
|
||||
@@ -109,8 +109,8 @@ class ServerProvider extends BusyProvider {
|
||||
|
||||
Future<void> startAutoRefresh() async {
|
||||
final duration = _settingStore.serverStatusUpdateInterval.fetch()!;
|
||||
if (duration == 0) return;
|
||||
stopAutoRefresh();
|
||||
if (duration == 0) return;
|
||||
_timer = Timer.periodic(Duration(seconds: duration), (_) async {
|
||||
await refreshData();
|
||||
});
|
||||
@@ -240,7 +240,7 @@ class ServerProvider extends BusyProvider {
|
||||
throw Exception(writeResult);
|
||||
}
|
||||
// reset try times if connected successfully
|
||||
_limiter.resetTryTimes(sid);
|
||||
_limiter.reset(sid);
|
||||
}
|
||||
|
||||
if (s.client == null) return;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
class BuildData {
|
||||
static const String name = "ServerBox";
|
||||
static const int build = 396;
|
||||
static const int build = 397;
|
||||
static const String engine = "3.10.6";
|
||||
static const String buildAt = "2023-07-28 19:15:52.944462";
|
||||
static const int modifications = 5;
|
||||
static const String buildAt = "2023-07-28 20:51:35.807892";
|
||||
static const int modifications = 6;
|
||||
}
|
||||
|
||||
@@ -28,14 +28,14 @@ const defaultSSHVirtKeys = [
|
||||
VirtKey.home,
|
||||
VirtKey.up,
|
||||
VirtKey.end,
|
||||
VirtKey.file,
|
||||
VirtKey.sftp,
|
||||
VirtKey.snippet,
|
||||
VirtKey.tab,
|
||||
VirtKey.ctrl,
|
||||
VirtKey.left,
|
||||
VirtKey.down,
|
||||
VirtKey.right,
|
||||
VirtKey.paste,
|
||||
VirtKey.clipboard,
|
||||
VirtKey.ime,
|
||||
];
|
||||
|
||||
|
||||
@@ -206,6 +206,8 @@
|
||||
"versionUnknownUpdate": "Aktuell: v1.0.{build}",
|
||||
"versionUpdated": "v1.0.{build} ist bereits die neueste Version",
|
||||
"viewErr": "Fehler anzeigen",
|
||||
"virtKeyHelpClipboard": "In die Zwischenablage kopieren, wenn das ausgewählte Terminal nicht leer ist, andernfalls den Inhalt der Zwischenablage in das Terminal einfügen.",
|
||||
"virtKeyHelpSFTP": "Aktuelles Verzeichnis in SFTP öffnen.",
|
||||
"waitConnection": "Bitte warte, bis die Verbindung hergestellt wurde.",
|
||||
"whenOpenApp": "Beim Öffnen der App",
|
||||
"willTakEeffectImmediately": "Wird sofort angewendet"
|
||||
|
||||
@@ -206,6 +206,8 @@
|
||||
"versionUnknownUpdate": "Current: v1.0.{build}",
|
||||
"versionUpdated": "Current: v1.0.{build}, is up to date",
|
||||
"viewErr": "See error",
|
||||
"virtKeyHelpClipboard": "Copy to the clipboard if terminal selected is not empty, otherwise paste the contents of the clipboard to the terminal.",
|
||||
"virtKeyHelpSFTP": "Open current directory in SFTP.",
|
||||
"waitConnection": "Please wait for the connection to be established.",
|
||||
"whenOpenApp": "When opening the app",
|
||||
"willTakEeffectImmediately": "Will take effect immediately"
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
"dockerEditHost": "Edit Docker_host",
|
||||
"dockerEmptyRunningItems": "Tidak ada wadah yang berjalan.\nMungkin saja env DOCKER_HOST tidak dibaca dengan benar. Anda dapat menemukannya dengan menjalankan `echo $DOCKER_HOST` di terminal.",
|
||||
"dockerImagesFmt": "{count} gambar",
|
||||
"dockerNotInstalled": "Docker tidak terpasang",
|
||||
"dockerNotInstalled": "Docker tidak terpasang",
|
||||
"dockerStatusRunningAndStoppedFmt": "{runningCount} running, {stoppedCount} container stopped.",
|
||||
"dockerStatusRunningFmt": "{count} wadah berjalan.",
|
||||
"download": "Unduh",
|
||||
@@ -206,6 +206,8 @@
|
||||
"versionUnknownUpdate": "Saat ini: v1.0.{build}",
|
||||
"versionUpdated": "Saat ini: v1.0.{build}, mutakhir",
|
||||
"viewErr": "Lihat kesalahan",
|
||||
"virtKeyHelpClipboard": "Salin ke clipboard jika terminal yang dipilih tidak kosong, jika tidak, tempel isi clipboard ke terminal.",
|
||||
"virtKeyHelpSFTP": "Buka direktori saat ini di SFTP.",
|
||||
"waitConnection": "Harap tunggu koneksi akan dibuat.",
|
||||
"whenOpenApp": "Saat membuka aplikasi",
|
||||
"willTakEeffectImmediately": "Akan segera berlaku"
|
||||
|
||||
@@ -206,6 +206,8 @@
|
||||
"versionUnknownUpdate": "当前:v1.0.{build}",
|
||||
"versionUpdated": "当前:v1.0.{build}, 已是最新版本",
|
||||
"viewErr": "查看错误",
|
||||
"virtKeyHelpClipboard": "如果终端有选中字符,则复制选中字符至剪切板,否则粘贴剪切板内容至终端。",
|
||||
"virtKeyHelpSFTP": "在 SFTP 中打开当前路径。",
|
||||
"waitConnection": "请等待连接建立",
|
||||
"whenOpenApp": "当打开 App 时",
|
||||
"willTakEeffectImmediately": "更改将会立即生效"
|
||||
|
||||
@@ -206,6 +206,8 @@
|
||||
"versionUnknownUpdate": "當前:v1.0.{build}",
|
||||
"versionUpdated": "當前:v1.0.{build}, 已是最新版本",
|
||||
"viewErr": "查看錯誤",
|
||||
"virtKeyHelpClipboard": "如果終端有選中字符,則復製選中字符至剪切板,否則粘貼剪切板內容至終端。",
|
||||
"virtKeyHelpSFTP": "在 SFTP 中打開當前路徑。",
|
||||
"waitConnection": "請等待連接建立",
|
||||
"whenOpenApp": "當打開 App 時",
|
||||
"willTakEeffectImmediately": "更改將會立即生效"
|
||||
|
||||
@@ -76,18 +76,6 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
|
||||
bottomNavigationBar: SafeArea(
|
||||
child: _buildPath(),
|
||||
),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: (() {
|
||||
if (_path!.path == _prefixPath) {
|
||||
showSnackBar(context, Text(_s.alreadyLastDir));
|
||||
return;
|
||||
}
|
||||
_path!.update('..');
|
||||
setState(() {});
|
||||
}),
|
||||
child: const Icon(Icons.keyboard_arrow_left),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -112,10 +100,22 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
|
||||
}
|
||||
final dir = Directory(_path!.path);
|
||||
final files = dir.listSync();
|
||||
final canGoBack = _path!.path != _prefixPath;
|
||||
return ListView.builder(
|
||||
itemCount: files.length,
|
||||
itemCount: canGoBack ? files.length + 1 : files.length,
|
||||
padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 7),
|
||||
itemBuilder: (context, index) {
|
||||
if (index == 0 && canGoBack) {
|
||||
return RoundRectCard(ListTile(
|
||||
leading: const Icon(Icons.keyboard_arrow_left),
|
||||
title: const Text('..'),
|
||||
onTap: () {
|
||||
_path!.update('..');
|
||||
setState(() {});
|
||||
},
|
||||
));
|
||||
}
|
||||
index = canGoBack ? index - 1 : index;
|
||||
var file = files[index];
|
||||
var fileName = file.path.split('/').last;
|
||||
var stat = file.statSync();
|
||||
|
||||
@@ -39,11 +39,9 @@ class _SSHPageState extends State<SSHPage> {
|
||||
final _setting = locator<SettingStore>();
|
||||
late final _terminal = Terminal(inputHandler: _keyboard);
|
||||
final TerminalController _terminalController = TerminalController();
|
||||
final ContextMenuController _menuController = ContextMenuController();
|
||||
final List<List<VirtKey>> _virtKeysList = [];
|
||||
|
||||
late MediaQueryData _media;
|
||||
late TextStyle _menuTextStyle;
|
||||
late S _s;
|
||||
late TerminalStyle _terminalStyle;
|
||||
late TerminalTheme _terminalTheme;
|
||||
@@ -75,7 +73,6 @@ class _SSHPageState extends State<SSHPage> {
|
||||
super.didChangeDependencies();
|
||||
_isDark = isDarkMode(context);
|
||||
_media = MediaQuery.of(context);
|
||||
_menuTextStyle = TextStyle(color: contentColor.resolve(context));
|
||||
_s = S.of(context)!;
|
||||
_terminalTheme = _isDark ? termDarkTheme : termLightTheme;
|
||||
// Calculate virtkey width / height
|
||||
@@ -118,8 +115,7 @@ class _SSHPageState extends State<SSHPage> {
|
||||
textStyle: _terminalStyle,
|
||||
theme: _terminalTheme,
|
||||
deleteDetection: isIOS,
|
||||
onTapUp: _onTapUp,
|
||||
autoFocus: true,
|
||||
autofocus: true,
|
||||
keyboardAppearance: _isDark ? Brightness.dark : Brightness.light,
|
||||
),
|
||||
);
|
||||
@@ -231,13 +227,12 @@ class _SSHPageState extends State<SSHPage> {
|
||||
case VirtualKeyFunc.backspace:
|
||||
_terminal.keyInput(TerminalKey.backspace);
|
||||
break;
|
||||
case VirtualKeyFunc.paste:
|
||||
_paste();
|
||||
break;
|
||||
case VirtualKeyFunc.copy:
|
||||
case VirtualKeyFunc.clipboard:
|
||||
final selected = terminalSelected;
|
||||
if (selected != null) {
|
||||
copy2Clipboard(selected);
|
||||
} else {
|
||||
_paste();
|
||||
}
|
||||
break;
|
||||
case VirtualKeyFunc.snippet:
|
||||
@@ -290,58 +285,12 @@ class _SSHPageState extends State<SSHPage> {
|
||||
return _terminal.buffer.getText(range);
|
||||
}
|
||||
|
||||
void _onTapUp(TapUpDetails details, CellOffset offset) {
|
||||
if (_menuController.isShown) {
|
||||
_menuController.remove();
|
||||
return;
|
||||
}
|
||||
final selected = terminalSelected;
|
||||
final children = <Widget>[
|
||||
// TextButton(
|
||||
// onPressed: () {
|
||||
// _paste();
|
||||
// },
|
||||
// child: Text(_s.paste),
|
||||
// ),
|
||||
];
|
||||
if (selected?.trim().isNotEmpty ?? false) {
|
||||
children.add(
|
||||
TextButton(
|
||||
child: Text(
|
||||
_s.copy,
|
||||
style: _menuTextStyle,
|
||||
),
|
||||
onPressed: () {
|
||||
_terminalController.setSelection(null);
|
||||
if (selected != null) {
|
||||
copy2Clipboard(selected);
|
||||
}
|
||||
_menuController.remove();
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
if (children.isEmpty) {
|
||||
return;
|
||||
}
|
||||
_menuController.show(
|
||||
context: context,
|
||||
contextMenuBuilder: (context) {
|
||||
return TextSelectionToolbar(
|
||||
anchorAbove: details.globalPosition,
|
||||
anchorBelow: details.globalPosition,
|
||||
children: children,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _write(String p0) {
|
||||
_terminal.write('$p0\r\n');
|
||||
}
|
||||
|
||||
void _initVirtKeys() {
|
||||
final virtKeys = _setting.sshVirtKeys.fetch()!;
|
||||
final virtKeys = List<VirtKey>.from(_setting.sshVirtKeys.fetchRaw());
|
||||
|
||||
for (int len = 0; len < virtKeys.length; len += 7) {
|
||||
if (len + 7 > virtKeys.length) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:nil/nil.dart';
|
||||
import 'package:toolbox/core/extension/order.dart';
|
||||
import 'package:toolbox/core/utils/platform.dart';
|
||||
import 'package:toolbox/core/utils/ui.dart';
|
||||
import 'package:toolbox/data/model/ssh/virtual_key.dart';
|
||||
import 'package:toolbox/data/res/ui.dart';
|
||||
import 'package:toolbox/data/store/setting.dart';
|
||||
import 'package:toolbox/locator.dart';
|
||||
import 'package:toolbox/view/widget/round_rect_card.dart';
|
||||
|
||||
class SSHVirtKeySettingPage extends StatefulWidget {
|
||||
const SSHVirtKeySettingPage({Key? key}) : super(key: key);
|
||||
@@ -44,17 +45,18 @@ class _SSHVirtKeySettingPageState extends State<SSHVirtKeySettingPage> {
|
||||
final disabled = VirtKey.values.where((e) => !keys.contains(e)).toList();
|
||||
final allKeys = [...keys, ...disabled];
|
||||
return ReorderableListView.builder(
|
||||
padding: const EdgeInsets.fromLTRB(11, 3, 0, 3),
|
||||
padding: const EdgeInsets.all(7),
|
||||
itemBuilder: (_, idx) {
|
||||
final key = allKeys[idx];
|
||||
return ListTile(
|
||||
key: ValueKey(idx),
|
||||
title: _buildTitle(key),
|
||||
leading: _buildCheckBox(keys, key, idx, idx < keys.length),
|
||||
trailing: isDesktop
|
||||
? nil
|
||||
: const Icon(Icons.drag_handle, color: Colors.grey),
|
||||
);
|
||||
final help = key.help(_s);
|
||||
return RoundRectCard(
|
||||
key: ValueKey(idx),
|
||||
ListTile(
|
||||
title: _buildTitle(key),
|
||||
subtitle: help == null ? null : Text(help, style: grey),
|
||||
leading: _buildCheckBox(keys, key, idx, idx < keys.length),
|
||||
trailing: isDesktop ? null : const Icon(Icons.drag_handle),
|
||||
));
|
||||
},
|
||||
itemCount: allKeys.length,
|
||||
onReorder: (o, n) {
|
||||
@@ -70,12 +72,8 @@ class _SSHVirtKeySettingPageState extends State<SSHVirtKeySettingPage> {
|
||||
|
||||
Widget _buildTitle(VirtKey key) {
|
||||
return key.icon == null
|
||||
? Text(
|
||||
key.text,
|
||||
textAlign: TextAlign.center,
|
||||
)
|
||||
? Text(key.text)
|
||||
: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(key.text),
|
||||
const SizedBox(width: 10),
|
||||
|
||||
Reference in New Issue
Block a user