mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
@@ -300,6 +300,12 @@ abstract class S {
|
|||||||
/// **'Delete'**
|
/// **'Delete'**
|
||||||
String get delete;
|
String get delete;
|
||||||
|
|
||||||
|
/// No description provided for @disabled.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Disabled'**
|
||||||
|
String get disabled;
|
||||||
|
|
||||||
/// No description provided for @disconnected.
|
/// No description provided for @disconnected.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
@@ -372,6 +378,12 @@ abstract class S {
|
|||||||
/// **'Edit'**
|
/// **'Edit'**
|
||||||
String get edit;
|
String get edit;
|
||||||
|
|
||||||
|
/// No description provided for @editVirtKeys.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Edit virtual keys'**
|
||||||
|
String get editVirtKeys;
|
||||||
|
|
||||||
/// No description provided for @editor.
|
/// No description provided for @editor.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
|
|||||||
@@ -106,6 +106,9 @@ class SDe extends S {
|
|||||||
@override
|
@override
|
||||||
String get delete => 'Löschen';
|
String get delete => 'Löschen';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get disabled => 'Disabled';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get disconnected => 'Disconnected';
|
String get disconnected => 'Disconnected';
|
||||||
|
|
||||||
@@ -152,6 +155,9 @@ class SDe extends S {
|
|||||||
@override
|
@override
|
||||||
String get edit => 'Bearbeiten';
|
String get edit => 'Bearbeiten';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get editVirtKeys => 'Edit virtual keys';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get editor => 'Editor';
|
String get editor => 'Editor';
|
||||||
|
|
||||||
|
|||||||
@@ -106,6 +106,9 @@ class SEn extends S {
|
|||||||
@override
|
@override
|
||||||
String get delete => 'Delete';
|
String get delete => 'Delete';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get disabled => 'Disabled';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get disconnected => 'Disconnected';
|
String get disconnected => 'Disconnected';
|
||||||
|
|
||||||
@@ -152,6 +155,9 @@ class SEn extends S {
|
|||||||
@override
|
@override
|
||||||
String get edit => 'Edit';
|
String get edit => 'Edit';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get editVirtKeys => 'Edit virtual keys';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get editor => 'Editor';
|
String get editor => 'Editor';
|
||||||
|
|
||||||
|
|||||||
@@ -106,6 +106,9 @@ class SZh extends S {
|
|||||||
@override
|
@override
|
||||||
String get delete => '删除';
|
String get delete => '删除';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get disabled => '已禁用';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get disconnected => '连接断开';
|
String get disconnected => '连接断开';
|
||||||
|
|
||||||
@@ -152,6 +155,9 @@ class SZh extends S {
|
|||||||
@override
|
@override
|
||||||
String get edit => '编辑';
|
String get edit => '编辑';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get editVirtKeys => '编辑虚拟按键';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get editor => '编辑器';
|
String get editor => '编辑器';
|
||||||
|
|
||||||
@@ -743,6 +749,9 @@ class SZhTw extends SZh {
|
|||||||
@override
|
@override
|
||||||
String get delete => '刪除';
|
String get delete => '刪除';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get disabled => '已禁用';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get disconnected => '連接斷開';
|
String get disconnected => '連接斷開';
|
||||||
|
|
||||||
@@ -789,6 +798,9 @@ class SZhTw extends SZh {
|
|||||||
@override
|
@override
|
||||||
String get edit => '編輯';
|
String get edit => '編輯';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get editVirtKeys => '編輯虛擬按鍵';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get editor => '編輯器';
|
String get editor => '編輯器';
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ PODS:
|
|||||||
- Flutter (1.0.0)
|
- Flutter (1.0.0)
|
||||||
- flutter_native_splash (0.0.1):
|
- flutter_native_splash (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- flutter_volume_controller (0.0.1):
|
||||||
|
- Flutter
|
||||||
- path_provider_foundation (0.0.1):
|
- path_provider_foundation (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
@@ -23,6 +25,7 @@ DEPENDENCIES:
|
|||||||
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
|
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
|
||||||
|
- flutter_volume_controller (from `.symlinks/plugins/flutter_volume_controller/ios`)
|
||||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
||||||
- plain_notification_token (from `.symlinks/plugins/plain_notification_token/ios`)
|
- plain_notification_token (from `.symlinks/plugins/plain_notification_token/ios`)
|
||||||
- r_upgrade (from `.symlinks/plugins/r_upgrade/ios`)
|
- r_upgrade (from `.symlinks/plugins/r_upgrade/ios`)
|
||||||
@@ -38,6 +41,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: Flutter
|
:path: Flutter
|
||||||
flutter_native_splash:
|
flutter_native_splash:
|
||||||
:path: ".symlinks/plugins/flutter_native_splash/ios"
|
:path: ".symlinks/plugins/flutter_native_splash/ios"
|
||||||
|
flutter_volume_controller:
|
||||||
|
:path: ".symlinks/plugins/flutter_volume_controller/ios"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
||||||
plain_notification_token:
|
plain_notification_token:
|
||||||
@@ -54,6 +59,7 @@ SPEC CHECKSUMS:
|
|||||||
file_picker: 1d63c4949e05e386da864365f8c13e1e64787675
|
file_picker: 1d63c4949e05e386da864365f8c13e1e64787675
|
||||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||||
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
|
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
|
||||||
|
flutter_volume_controller: e4d5832f08008180f76e30faf671ffd5a425e529
|
||||||
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
|
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
|
||||||
plain_notification_token: b36467dc91939a7b6754267c701bbaca14996ee1
|
plain_notification_token: b36467dc91939a7b6754267c701bbaca14996ee1
|
||||||
r_upgrade: 44d715c61914cce3d01ea225abffe894fd51c114
|
r_upgrade: 44d715c61914cce3d01ea225abffe894fd51c114
|
||||||
@@ -62,4 +68,4 @@ SPEC CHECKSUMS:
|
|||||||
|
|
||||||
PODFILE CHECKSUM: 7fb15c416f8685fca4966867a8da218ec592ec2e
|
PODFILE CHECKSUM: 7fb15c416f8685fca4966867a8da218ec592ec2e
|
||||||
|
|
||||||
COCOAPODS: 1.11.1
|
COCOAPODS: 1.12.1
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import 'package:toolbox/core/persistant_store.dart';
|
import 'package:toolbox/core/persistant_store.dart';
|
||||||
|
|
||||||
typedef StringOrder = List<String>;
|
typedef Order<T> = List<T>;
|
||||||
|
|
||||||
extension StringOrderX on StringOrder {
|
extension OrderX<T> on Order<T> {
|
||||||
void move(int oldIndex, int newIndex, StoreProperty property) {
|
void move(int oldIndex, int newIndex, StoreProperty<List<T>> property) {
|
||||||
if (oldIndex == newIndex) return;
|
if (oldIndex == newIndex) return;
|
||||||
if (oldIndex < newIndex) {
|
if (oldIndex < newIndex) {
|
||||||
newIndex -= 1;
|
newIndex -= 1;
|
||||||
@@ -14,17 +14,17 @@ extension StringOrderX on StringOrder {
|
|||||||
property.put(this);
|
property.put(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(String id, String newId) {
|
void update(T id, T newId) {
|
||||||
final index = indexOf(id);
|
final index = indexOf(id);
|
||||||
if (index == -1) return;
|
if (index == -1) return;
|
||||||
this[index] = newId;
|
this[index] = newId;
|
||||||
}
|
}
|
||||||
|
|
||||||
int index(String id) {
|
int index(T id) {
|
||||||
return indexOf(id);
|
return indexOf(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void moveById(String oid, String nid, StoreProperty property) {
|
void moveById(T oid, T nid, StoreProperty<List<T>> property) {
|
||||||
final index = indexOf(oid);
|
final index = indexOf(oid);
|
||||||
if (index == -1) return;
|
if (index == -1) return;
|
||||||
final newIndex = indexOf(nid);
|
final newIndex = indexOf(nid);
|
||||||
|
|||||||
@@ -1,20 +1,151 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hive_flutter/hive_flutter.dart';
|
||||||
import 'package:xterm/core.dart';
|
import 'package:xterm/core.dart';
|
||||||
|
|
||||||
class VirtualKey {
|
part 'virtual_key.g.dart';
|
||||||
final String text;
|
|
||||||
final bool toggleable;
|
|
||||||
final TerminalKey? key;
|
|
||||||
final IconData? icon;
|
|
||||||
final VirtualKeyFunc? func;
|
|
||||||
|
|
||||||
VirtualKey(
|
@HiveType(typeId: 4)
|
||||||
this.text, {
|
enum VirtKey {
|
||||||
this.key,
|
@HiveField(0)
|
||||||
this.toggleable = false,
|
esc,
|
||||||
this.icon,
|
@HiveField(1)
|
||||||
this.func,
|
alt,
|
||||||
});
|
@HiveField(2)
|
||||||
|
home,
|
||||||
|
@HiveField(3)
|
||||||
|
up,
|
||||||
|
@HiveField(4)
|
||||||
|
end,
|
||||||
|
@HiveField(5)
|
||||||
|
file,
|
||||||
|
@HiveField(6)
|
||||||
|
snippet,
|
||||||
|
@HiveField(7)
|
||||||
|
tab,
|
||||||
|
@HiveField(8)
|
||||||
|
ctrl,
|
||||||
|
@HiveField(9)
|
||||||
|
left,
|
||||||
|
@HiveField(10)
|
||||||
|
down,
|
||||||
|
@HiveField(11)
|
||||||
|
right,
|
||||||
|
@HiveField(12)
|
||||||
|
paste,
|
||||||
|
@HiveField(13)
|
||||||
|
ime,
|
||||||
|
@HiveField(14)
|
||||||
|
pgup,
|
||||||
|
@HiveField(15)
|
||||||
|
pgdn;
|
||||||
|
|
||||||
|
String get text {
|
||||||
|
switch (this) {
|
||||||
|
case VirtKey.pgdn:
|
||||||
|
return 'PgDn';
|
||||||
|
case VirtKey.pgup:
|
||||||
|
return 'PgUp';
|
||||||
|
default:
|
||||||
|
if (name.length > 1) {
|
||||||
|
return name.substring(0, 1).toUpperCase() + name.substring(1);
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TerminalKey? get key {
|
||||||
|
switch (this) {
|
||||||
|
case VirtKey.esc:
|
||||||
|
return TerminalKey.escape;
|
||||||
|
case VirtKey.alt:
|
||||||
|
return TerminalKey.alt;
|
||||||
|
case VirtKey.home:
|
||||||
|
return TerminalKey.home;
|
||||||
|
case VirtKey.up:
|
||||||
|
return TerminalKey.arrowUp;
|
||||||
|
case VirtKey.end:
|
||||||
|
return TerminalKey.end;
|
||||||
|
case VirtKey.tab:
|
||||||
|
return TerminalKey.tab;
|
||||||
|
case VirtKey.ctrl:
|
||||||
|
return TerminalKey.control;
|
||||||
|
case VirtKey.left:
|
||||||
|
return TerminalKey.arrowLeft;
|
||||||
|
case VirtKey.down:
|
||||||
|
return TerminalKey.arrowDown;
|
||||||
|
case VirtKey.right:
|
||||||
|
return TerminalKey.arrowRight;
|
||||||
|
case VirtKey.pgup:
|
||||||
|
return TerminalKey.pageUp;
|
||||||
|
case VirtKey.pgdn:
|
||||||
|
return TerminalKey.pageDown;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IconData? get icon {
|
||||||
|
switch (this) {
|
||||||
|
case VirtKey.up:
|
||||||
|
return Icons.arrow_upward;
|
||||||
|
case VirtKey.left:
|
||||||
|
return Icons.arrow_back;
|
||||||
|
case VirtKey.down:
|
||||||
|
return Icons.arrow_downward;
|
||||||
|
case VirtKey.right:
|
||||||
|
return Icons.arrow_forward;
|
||||||
|
case VirtKey.file:
|
||||||
|
return Icons.file_open;
|
||||||
|
case VirtKey.snippet:
|
||||||
|
return Icons.code;
|
||||||
|
case VirtKey.paste:
|
||||||
|
return Icons.paste;
|
||||||
|
case VirtKey.ime:
|
||||||
|
return Icons.keyboard_hide;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use [VirtualKeyFunc] instead of [VirtKey]
|
||||||
|
// This can help linter to enum all [VirtualKeyFunc]
|
||||||
|
// and make sure all [VirtualKeyFunc] are handled
|
||||||
|
VirtualKeyFunc? get func {
|
||||||
|
switch (this) {
|
||||||
|
case VirtKey.file:
|
||||||
|
return VirtualKeyFunc.file;
|
||||||
|
case VirtKey.snippet:
|
||||||
|
return VirtualKeyFunc.snippet;
|
||||||
|
case VirtKey.paste:
|
||||||
|
return VirtualKeyFunc.paste;
|
||||||
|
case VirtKey.ime:
|
||||||
|
return VirtualKeyFunc.toggleIME;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get toggleable {
|
||||||
|
switch (this) {
|
||||||
|
case VirtKey.alt:
|
||||||
|
case VirtKey.ctrl:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get canLongPress {
|
||||||
|
switch (this) {
|
||||||
|
case VirtKey.up:
|
||||||
|
case VirtKey.left:
|
||||||
|
case VirtKey.down:
|
||||||
|
case VirtKey.right:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum VirtualKeyFunc { toggleIME, backspace, copy, paste, snippet, file }
|
enum VirtualKeyFunc { toggleIME, backspace, copy, paste, snippet, file }
|
||||||
|
|||||||
116
lib/data/model/ssh/virtual_key.g.dart
Normal file
116
lib/data/model/ssh/virtual_key.g.dart
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'virtual_key.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// TypeAdapterGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
class VirtKeyAdapter extends TypeAdapter<VirtKey> {
|
||||||
|
@override
|
||||||
|
final int typeId = 4;
|
||||||
|
|
||||||
|
@override
|
||||||
|
VirtKey read(BinaryReader reader) {
|
||||||
|
switch (reader.readByte()) {
|
||||||
|
case 0:
|
||||||
|
return VirtKey.esc;
|
||||||
|
case 1:
|
||||||
|
return VirtKey.alt;
|
||||||
|
case 2:
|
||||||
|
return VirtKey.home;
|
||||||
|
case 3:
|
||||||
|
return VirtKey.up;
|
||||||
|
case 4:
|
||||||
|
return VirtKey.end;
|
||||||
|
case 5:
|
||||||
|
return VirtKey.file;
|
||||||
|
case 6:
|
||||||
|
return VirtKey.snippet;
|
||||||
|
case 7:
|
||||||
|
return VirtKey.tab;
|
||||||
|
case 8:
|
||||||
|
return VirtKey.ctrl;
|
||||||
|
case 9:
|
||||||
|
return VirtKey.left;
|
||||||
|
case 10:
|
||||||
|
return VirtKey.down;
|
||||||
|
case 11:
|
||||||
|
return VirtKey.right;
|
||||||
|
case 12:
|
||||||
|
return VirtKey.paste;
|
||||||
|
case 13:
|
||||||
|
return VirtKey.ime;
|
||||||
|
case 14:
|
||||||
|
return VirtKey.pgup;
|
||||||
|
case 15:
|
||||||
|
return VirtKey.pgdn;
|
||||||
|
default:
|
||||||
|
return VirtKey.esc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void write(BinaryWriter writer, VirtKey obj) {
|
||||||
|
switch (obj) {
|
||||||
|
case VirtKey.esc:
|
||||||
|
writer.writeByte(0);
|
||||||
|
break;
|
||||||
|
case VirtKey.alt:
|
||||||
|
writer.writeByte(1);
|
||||||
|
break;
|
||||||
|
case VirtKey.home:
|
||||||
|
writer.writeByte(2);
|
||||||
|
break;
|
||||||
|
case VirtKey.up:
|
||||||
|
writer.writeByte(3);
|
||||||
|
break;
|
||||||
|
case VirtKey.end:
|
||||||
|
writer.writeByte(4);
|
||||||
|
break;
|
||||||
|
case VirtKey.file:
|
||||||
|
writer.writeByte(5);
|
||||||
|
break;
|
||||||
|
case VirtKey.snippet:
|
||||||
|
writer.writeByte(6);
|
||||||
|
break;
|
||||||
|
case VirtKey.tab:
|
||||||
|
writer.writeByte(7);
|
||||||
|
break;
|
||||||
|
case VirtKey.ctrl:
|
||||||
|
writer.writeByte(8);
|
||||||
|
break;
|
||||||
|
case VirtKey.left:
|
||||||
|
writer.writeByte(9);
|
||||||
|
break;
|
||||||
|
case VirtKey.down:
|
||||||
|
writer.writeByte(10);
|
||||||
|
break;
|
||||||
|
case VirtKey.right:
|
||||||
|
writer.writeByte(11);
|
||||||
|
break;
|
||||||
|
case VirtKey.paste:
|
||||||
|
writer.writeByte(12);
|
||||||
|
break;
|
||||||
|
case VirtKey.ime:
|
||||||
|
writer.writeByte(13);
|
||||||
|
break;
|
||||||
|
case VirtKey.pgup:
|
||||||
|
writer.writeByte(14);
|
||||||
|
break;
|
||||||
|
case VirtKey.pgdn:
|
||||||
|
writer.writeByte(15);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => typeId.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
other is VirtKeyAdapter &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
typeId == other.typeId;
|
||||||
|
}
|
||||||
@@ -23,8 +23,8 @@ typedef ServersMap = Map<String, Server>;
|
|||||||
class ServerProvider extends BusyProvider {
|
class ServerProvider extends BusyProvider {
|
||||||
final ServersMap _servers = {};
|
final ServersMap _servers = {};
|
||||||
ServersMap get servers => _servers;
|
ServersMap get servers => _servers;
|
||||||
final StringOrder _serverOrder = [];
|
final Order<String> _serverOrder = [];
|
||||||
StringOrder get serverOrder => _serverOrder;
|
Order get serverOrder => _serverOrder;
|
||||||
final List<String> _tags = [];
|
final List<String> _tags = [];
|
||||||
List<String> get tags => _tags;
|
List<String> get tags => _tags;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
|
import 'package:toolbox/data/model/ssh/virtual_key.dart';
|
||||||
|
|
||||||
// default server details page cards order
|
// default server details page cards order
|
||||||
const defaultDetailCardOrder = [
|
const defaultDetailCardOrder = [
|
||||||
'uptime',
|
'uptime',
|
||||||
@@ -20,6 +22,23 @@ const defaultDiskIgnorePath = [
|
|||||||
'none',
|
'none',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const defaultSSHVirtKeys = [
|
||||||
|
VirtKey.esc,
|
||||||
|
VirtKey.alt,
|
||||||
|
VirtKey.home,
|
||||||
|
VirtKey.up,
|
||||||
|
VirtKey.end,
|
||||||
|
VirtKey.file,
|
||||||
|
VirtKey.snippet,
|
||||||
|
VirtKey.tab,
|
||||||
|
VirtKey.ctrl,
|
||||||
|
VirtKey.left,
|
||||||
|
VirtKey.down,
|
||||||
|
VirtKey.right,
|
||||||
|
VirtKey.paste,
|
||||||
|
VirtKey.ime,
|
||||||
|
];
|
||||||
|
|
||||||
const defaultPrimaryColor = Color.fromARGB(255, 145, 58, 31);
|
const defaultPrimaryColor = Color.fromARGB(255, 145, 58, 31);
|
||||||
|
|
||||||
const defaultLaunchPageIdx = 0;
|
const defaultLaunchPageIdx = 0;
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:xterm/core.dart';
|
|
||||||
|
|
||||||
import '../model/ssh/virtual_key.dart';
|
|
||||||
|
|
||||||
final virtualKeys = [
|
|
||||||
VirtualKey('Esc', key: TerminalKey.escape),
|
|
||||||
VirtualKey('Alt', key: TerminalKey.alt, toggleable: true),
|
|
||||||
VirtualKey('Home', key: TerminalKey.home),
|
|
||||||
VirtualKey('Up', key: TerminalKey.arrowUp, icon: Icons.arrow_upward),
|
|
||||||
VirtualKey('End', key: TerminalKey.end),
|
|
||||||
VirtualKey(
|
|
||||||
'File',
|
|
||||||
func: VirtualKeyFunc.file,
|
|
||||||
icon: Icons.file_open,
|
|
||||||
),
|
|
||||||
VirtualKey('Snippet', func: VirtualKeyFunc.snippet, icon: Icons.code),
|
|
||||||
VirtualKey('Tab', key: TerminalKey.tab),
|
|
||||||
VirtualKey('Ctrl', key: TerminalKey.control, toggleable: true),
|
|
||||||
VirtualKey('Left', key: TerminalKey.arrowLeft, icon: Icons.arrow_back),
|
|
||||||
VirtualKey('Down', key: TerminalKey.arrowDown, icon: Icons.arrow_downward),
|
|
||||||
VirtualKey('Right', key: TerminalKey.arrowRight, icon: Icons.arrow_forward),
|
|
||||||
VirtualKey('Paste', func: VirtualKeyFunc.paste, icon: Icons.paste),
|
|
||||||
VirtualKey(
|
|
||||||
'IME',
|
|
||||||
func: VirtualKeyFunc.toggleIME,
|
|
||||||
icon: Icons.keyboard_hide,
|
|
||||||
),
|
|
||||||
];
|
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:toolbox/core/persistant_store.dart';
|
import 'package:toolbox/core/persistant_store.dart';
|
||||||
import 'package:toolbox/core/utils/platform.dart';
|
import 'package:toolbox/core/utils/platform.dart';
|
||||||
|
import 'package:toolbox/data/model/ssh/virtual_key.dart';
|
||||||
|
|
||||||
import '../res/default.dart';
|
import '../res/default.dart';
|
||||||
|
|
||||||
class SettingStore extends PersistentStore {
|
class SettingStore extends PersistentStore {
|
||||||
StoreProperty<int> get primaryColor => property(
|
StoreProperty<int> get primaryColor => property<int>(
|
||||||
'primaryColor',
|
'primaryColor',
|
||||||
defaultValue: 4287106639,
|
defaultValue: 4287106639,
|
||||||
);
|
);
|
||||||
@@ -76,4 +77,7 @@ class SettingStore extends PersistentStore {
|
|||||||
|
|
||||||
StoreProperty<int> get keyboardType =>
|
StoreProperty<int> get keyboardType =>
|
||||||
property('keyboardType', defaultValue: TextInputType.text.index);
|
property('keyboardType', defaultValue: TextInputType.text.index);
|
||||||
|
|
||||||
|
StoreProperty<List<VirtKey>> get sshVirtKeys =>
|
||||||
|
property('sshVirtKeys', defaultValue: defaultSSHVirtKeys);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
"debug": "Debug",
|
"debug": "Debug",
|
||||||
"decode": "Decode",
|
"decode": "Decode",
|
||||||
"delete": "Delete",
|
"delete": "Delete",
|
||||||
|
"disabled": "Disabled",
|
||||||
"disconnected": "Disconnected",
|
"disconnected": "Disconnected",
|
||||||
"diskIgnorePath": "Ignore path for disk",
|
"diskIgnorePath": "Ignore path for disk",
|
||||||
"dl2Local": "Download {fileName} to local?",
|
"dl2Local": "Download {fileName} to local?",
|
||||||
@@ -46,6 +47,7 @@
|
|||||||
"download": "Download",
|
"download": "Download",
|
||||||
"downloadStatus": "{percent}% of {size}",
|
"downloadStatus": "{percent}% of {size}",
|
||||||
"edit": "Edit",
|
"edit": "Edit",
|
||||||
|
"editVirtKeys": "Edit virtual keys",
|
||||||
"editor": "Editor",
|
"editor": "Editor",
|
||||||
"encode": "Encode",
|
"encode": "Encode",
|
||||||
"error": "Error",
|
"error": "Error",
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
"debug": "调试",
|
"debug": "调试",
|
||||||
"decode": "解码",
|
"decode": "解码",
|
||||||
"delete": "删除",
|
"delete": "删除",
|
||||||
|
"disabled": "已禁用",
|
||||||
"disconnected": "连接断开",
|
"disconnected": "连接断开",
|
||||||
"diskIgnorePath": "忽略的磁盘路径",
|
"diskIgnorePath": "忽略的磁盘路径",
|
||||||
"dl2Local": "下载 {fileName} 到本地?",
|
"dl2Local": "下载 {fileName} 到本地?",
|
||||||
@@ -46,6 +47,7 @@
|
|||||||
"download": "下载",
|
"download": "下载",
|
||||||
"downloadStatus": "{size} 的 {percent}%",
|
"downloadStatus": "{size} 的 {percent}%",
|
||||||
"edit": "编辑",
|
"edit": "编辑",
|
||||||
|
"editVirtKeys": "编辑虚拟按键",
|
||||||
"editor": "编辑器",
|
"editor": "编辑器",
|
||||||
"encode": "编码",
|
"encode": "编码",
|
||||||
"error": "错误",
|
"error": "错误",
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
"debug": "調試",
|
"debug": "調試",
|
||||||
"decode": "解碼",
|
"decode": "解碼",
|
||||||
"delete": "刪除",
|
"delete": "刪除",
|
||||||
|
"disabled": "已禁用",
|
||||||
"disconnected": "連接斷開",
|
"disconnected": "連接斷開",
|
||||||
"diskIgnorePath": "忽略的磁盤路徑",
|
"diskIgnorePath": "忽略的磁盤路徑",
|
||||||
"dl2Local": "下載 {fileName} 到本地?",
|
"dl2Local": "下載 {fileName} 到本地?",
|
||||||
@@ -46,6 +47,7 @@
|
|||||||
"download": "下載",
|
"download": "下載",
|
||||||
"downloadStatus": "{size} 的 {percent}%",
|
"downloadStatus": "{size} 的 {percent}%",
|
||||||
"edit": "編輯",
|
"edit": "編輯",
|
||||||
|
"editVirtKeys": "編輯虛擬按鍵",
|
||||||
"editor": "編輯器",
|
"editor": "編輯器",
|
||||||
"encode": "編碼",
|
"encode": "編碼",
|
||||||
"error": "錯誤",
|
"error": "錯誤",
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'package:flutter/material.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:toolbox/data/model/ssh/virtual_key.dart';
|
||||||
|
|
||||||
import 'app.dart';
|
import 'app.dart';
|
||||||
import 'core/analysis.dart';
|
import 'core/analysis.dart';
|
||||||
@@ -47,6 +48,7 @@ Future<void> initApp() async {
|
|||||||
Future<void> initHive() async {
|
Future<void> initHive() async {
|
||||||
await Hive.initFlutter();
|
await Hive.initFlutter();
|
||||||
Hive.registerAdapter(SnippetAdapter());
|
Hive.registerAdapter(SnippetAdapter());
|
||||||
|
Hive.registerAdapter(VirtKeyAdapter());
|
||||||
Hive.registerAdapter(PrivateKeyInfoAdapter());
|
Hive.registerAdapter(PrivateKeyInfoAdapter());
|
||||||
Hive.registerAdapter(ServerPrivateInfoAdapter());
|
Hive.registerAdapter(ServerPrivateInfoAdapter());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:toolbox/core/extension/navigator.dart';
|
import 'package:toolbox/core/extension/navigator.dart';
|
||||||
import 'package:toolbox/core/route.dart';
|
import 'package:toolbox/core/route.dart';
|
||||||
import 'package:toolbox/view/page/ssh.dart';
|
import 'package:toolbox/view/page/ssh/term.dart';
|
||||||
import 'package:toolbox/view/widget/input_field.dart';
|
import 'package:toolbox/view/widget/input_field.dart';
|
||||||
|
|
||||||
import '../../core/utils/ui.dart';
|
import '../../core/utils/ui.dart';
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
|||||||
with SingleTickerProviderStateMixin {
|
with SingleTickerProviderStateMixin {
|
||||||
late MediaQueryData _media;
|
late MediaQueryData _media;
|
||||||
late S _s;
|
late S _s;
|
||||||
final StringOrder _cardsOrder = [];
|
final Order _cardsOrder = [];
|
||||||
final _setting = locator<SettingStore>();
|
final _setting = locator<SettingStore>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import '../../widget/round_rect_card.dart';
|
|||||||
import '../docker.dart';
|
import '../docker.dart';
|
||||||
import '../pkg.dart';
|
import '../pkg.dart';
|
||||||
import '../sftp/remote.dart';
|
import '../sftp/remote.dart';
|
||||||
import '../ssh.dart';
|
import '../ssh/term.dart';
|
||||||
import 'detail.dart';
|
import 'detail.dart';
|
||||||
import 'edit.dart';
|
import 'edit.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ import 'package:flutter_material_color_picker/flutter_material_color_picker.dart
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:toolbox/core/extension/locale.dart';
|
import 'package:toolbox/core/extension/locale.dart';
|
||||||
import 'package:toolbox/core/extension/navigator.dart';
|
import 'package:toolbox/core/extension/navigator.dart';
|
||||||
|
import 'package:toolbox/core/route.dart';
|
||||||
import 'package:toolbox/data/model/app/tab.dart';
|
import 'package:toolbox/data/model/app/tab.dart';
|
||||||
|
import 'package:toolbox/view/page/ssh/virt_key_setting.dart';
|
||||||
import 'package:toolbox/view/widget/input_field.dart';
|
import 'package:toolbox/view/widget/input_field.dart';
|
||||||
import 'package:toolbox/view/widget/value_notifier.dart';
|
import 'package:toolbox/view/widget/value_notifier.dart';
|
||||||
|
|
||||||
@@ -165,6 +167,7 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
_buildTermFontSize(),
|
_buildTermFontSize(),
|
||||||
_buildSSHVirtualKeyAutoOff(),
|
_buildSSHVirtualKeyAutoOff(),
|
||||||
_buildKeyboardType(),
|
_buildKeyboardType(),
|
||||||
|
_buildSSHVirtKeys(),
|
||||||
].map((e) => RoundRectCard(e)).toList(),
|
].map((e) => RoundRectCard(e)).toList(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -739,4 +742,15 @@ class _SettingPageState extends State<SettingPage> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildSSHVirtKeys() {
|
||||||
|
return ListTile(
|
||||||
|
title: Text(_s.editVirtKeys),
|
||||||
|
trailing: const Icon(Icons.arrow_forward_ios, size: 13),
|
||||||
|
onTap: () => AppRoute(
|
||||||
|
const SSHVirtKeySettingPage(),
|
||||||
|
'ssh virt key edit',
|
||||||
|
).go(context),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:dartssh2/dartssh2.dart';
|
import 'package:dartssh2/dartssh2.dart';
|
||||||
@@ -10,20 +11,19 @@ import 'package:toolbox/core/extension/navigator.dart';
|
|||||||
import 'package:toolbox/data/res/server_cmd.dart';
|
import 'package:toolbox/data/res/server_cmd.dart';
|
||||||
import 'package:xterm/xterm.dart';
|
import 'package:xterm/xterm.dart';
|
||||||
|
|
||||||
import '../../core/route.dart';
|
import '../../../core/route.dart';
|
||||||
import '../../core/utils/platform.dart';
|
import '../../../core/utils/platform.dart';
|
||||||
import '../../core/utils/misc.dart';
|
import '../../../core/utils/misc.dart';
|
||||||
import '../../core/utils/ui.dart';
|
import '../../../core/utils/ui.dart';
|
||||||
import '../../core/utils/server.dart';
|
import '../../../core/utils/server.dart';
|
||||||
import '../../data/model/server/server_private_info.dart';
|
import '../../../data/model/server/server_private_info.dart';
|
||||||
import '../../data/model/ssh/virtual_key.dart';
|
import '../../../data/model/ssh/virtual_key.dart';
|
||||||
import '../../data/provider/virtual_keyboard.dart';
|
import '../../../data/provider/virtual_keyboard.dart';
|
||||||
import '../../data/res/color.dart';
|
import '../../../data/res/color.dart';
|
||||||
import '../../data/res/terminal.dart';
|
import '../../../data/res/terminal.dart';
|
||||||
import '../../data/res/virtual_key.dart';
|
import '../../../data/store/setting.dart';
|
||||||
import '../../data/store/setting.dart';
|
import '../../../locator.dart';
|
||||||
import '../../locator.dart';
|
import '../sftp/remote.dart';
|
||||||
import 'sftp/remote.dart';
|
|
||||||
|
|
||||||
class SSHPage extends StatefulWidget {
|
class SSHPage extends StatefulWidget {
|
||||||
final ServerPrivateInfo spi;
|
final ServerPrivateInfo spi;
|
||||||
@@ -35,22 +35,26 @@ class SSHPage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _SSHPageState extends State<SSHPage> {
|
class _SSHPageState extends State<SSHPage> {
|
||||||
late final _terminal = Terminal(inputHandler: _keyboard);
|
|
||||||
SSHClient? _client;
|
|
||||||
late SSHSession _session;
|
|
||||||
final _keyboard = locator<VirtualKeyboard>();
|
final _keyboard = locator<VirtualKeyboard>();
|
||||||
final _setting = locator<SettingStore>();
|
final _setting = locator<SettingStore>();
|
||||||
late MediaQueryData _media;
|
late final _terminal = Terminal(inputHandler: _keyboard);
|
||||||
final _virtualKeyboardHeight = 57.0;
|
|
||||||
final TerminalController _terminalController = TerminalController();
|
final TerminalController _terminalController = TerminalController();
|
||||||
final ContextMenuController _menuController = ContextMenuController();
|
final ContextMenuController _menuController = ContextMenuController();
|
||||||
|
final List<List<VirtKey>> _virtKeysList = [];
|
||||||
|
|
||||||
|
late MediaQueryData _media;
|
||||||
late TextStyle _menuTextStyle;
|
late TextStyle _menuTextStyle;
|
||||||
late S _s;
|
late S _s;
|
||||||
late TerminalStyle _terminalStyle;
|
late TerminalStyle _terminalStyle;
|
||||||
late TerminalTheme _terminalTheme;
|
late TerminalTheme _terminalTheme;
|
||||||
late TextInputType _keyboardType;
|
late TextInputType _keyboardType;
|
||||||
|
late SSHSession _session;
|
||||||
|
late double _virtKeyWidth;
|
||||||
|
late double _virtKeysHeight;
|
||||||
|
|
||||||
var _isDark = false;
|
bool _isDark = false;
|
||||||
|
Timer? _virtKeyLongPressTimer;
|
||||||
|
SSHClient? _client;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -62,7 +66,8 @@ class _SSHPageState extends State<SSHPage> {
|
|||||||
);
|
);
|
||||||
_terminalStyle = TerminalStyle.fromTextStyle(textStyle);
|
_terminalStyle = TerminalStyle.fromTextStyle(textStyle);
|
||||||
_keyboardType = TextInputType.values[_setting.keyboardType.fetch()!];
|
_keyboardType = TextInputType.values[_setting.keyboardType.fetch()!];
|
||||||
initTerminal();
|
_initTerminal();
|
||||||
|
_initVirtKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -73,6 +78,9 @@ class _SSHPageState extends State<SSHPage> {
|
|||||||
_menuTextStyle = TextStyle(color: contentColor.resolve(context));
|
_menuTextStyle = TextStyle(color: contentColor.resolve(context));
|
||||||
_s = S.of(context)!;
|
_s = S.of(context)!;
|
||||||
_terminalTheme = _isDark ? termDarkTheme : termLightTheme;
|
_terminalTheme = _isDark ? termDarkTheme : termLightTheme;
|
||||||
|
// Calculate virtkey width / height
|
||||||
|
_virtKeyWidth = _media.size.width / 7;
|
||||||
|
_virtKeysHeight = _media.size.height * 0.047 * _virtKeysList.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -100,7 +108,7 @@ class _SSHPageState extends State<SSHPage> {
|
|||||||
Widget _buildBody() {
|
Widget _buildBody() {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: _media.size.height -
|
height: _media.size.height -
|
||||||
_virtualKeyboardHeight -
|
_virtKeysHeight -
|
||||||
_media.padding.bottom -
|
_media.padding.bottom -
|
||||||
_media.padding.top,
|
_media.padding.top,
|
||||||
child: TerminalView(
|
child: TerminalView(
|
||||||
@@ -125,7 +133,7 @@ class _SSHPageState extends State<SSHPage> {
|
|||||||
curve: Curves.fastOutSlowIn,
|
curve: Curves.fastOutSlowIn,
|
||||||
child: Container(
|
child: Container(
|
||||||
color: _terminalTheme.background,
|
color: _terminalTheme.background,
|
||||||
height: _virtualKeyboardHeight,
|
height: _virtKeysHeight,
|
||||||
child: Consumer<VirtualKeyboard>(
|
child: Consumer<VirtualKeyboard>(
|
||||||
builder: (_, __, ___) => _buildVirtualKey(),
|
builder: (_, __, ___) => _buildVirtualKey(),
|
||||||
),
|
),
|
||||||
@@ -135,23 +143,18 @@ class _SSHPageState extends State<SSHPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildVirtualKey() {
|
Widget _buildVirtualKey() {
|
||||||
final half = virtualKeys.length ~/ 2;
|
final rows = _virtKeysList
|
||||||
final top = virtualKeys.sublist(0, half);
|
.map((e) => Row(
|
||||||
final bottom = virtualKeys.sublist(half);
|
children: e.map((ee) => _buildVirtualKeyItem(ee)).toList(),
|
||||||
|
))
|
||||||
|
.toList();
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: rows,
|
||||||
Row(
|
|
||||||
children: top.map((e) => _buildVirtualKeyItem(e)).toList(),
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
children: bottom.map((e) => _buildVirtualKeyItem(e)).toList(),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildVirtualKeyItem(VirtualKey item) {
|
Widget _buildVirtualKeyItem(VirtKey item) {
|
||||||
var selected = false;
|
var selected = false;
|
||||||
switch (item.key) {
|
switch (item.key) {
|
||||||
case TerminalKey.control:
|
case TerminalKey.control:
|
||||||
@@ -176,9 +179,19 @@ class _SSHPageState extends State<SSHPage> {
|
|||||||
|
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () => _doVirtualKey(item),
|
onTap: () => _doVirtualKey(item),
|
||||||
|
onTapDown: (details) {
|
||||||
|
if (item.canLongPress) {
|
||||||
|
_virtKeyLongPressTimer = Timer.periodic(
|
||||||
|
const Duration(milliseconds: 137),
|
||||||
|
(_) => _doVirtualKey(item),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onTapCancel: () => _virtKeyLongPressTimer?.cancel(),
|
||||||
|
onTapUp: (_) => _virtKeyLongPressTimer?.cancel(),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: _media.size.width / (virtualKeys.length / 2),
|
width: _virtKeyWidth,
|
||||||
height: _virtualKeyboardHeight / 2,
|
height: _virtKeysHeight / _virtKeysList.length,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
@@ -186,7 +199,7 @@ class _SSHPageState extends State<SSHPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _doVirtualKey(VirtualKey item) {
|
void _doVirtualKey(VirtKey item) {
|
||||||
if (item.func != null) {
|
if (item.func != null) {
|
||||||
_doVirtualKeyFunc(item.func!);
|
_doVirtualKeyFunc(item.func!);
|
||||||
return;
|
return;
|
||||||
@@ -326,7 +339,19 @@ class _SSHPageState extends State<SSHPage> {
|
|||||||
_terminal.write('$p0\r\n');
|
_terminal.write('$p0\r\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> initTerminal() async {
|
void _initVirtKeys() {
|
||||||
|
final virtKeys = _setting.sshVirtKeys.fetch()!;
|
||||||
|
|
||||||
|
for (int len = 0; len < virtKeys.length; len += 7) {
|
||||||
|
if (len + 7 > virtKeys.length) {
|
||||||
|
_virtKeysList.add(virtKeys.sublist(len));
|
||||||
|
} else {
|
||||||
|
_virtKeysList.add(virtKeys.sublist(len, len + 7));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _initTerminal() async {
|
||||||
_write('Connecting...\r\n');
|
_write('Connecting...\r\n');
|
||||||
|
|
||||||
_client = await genClient(
|
_client = await genClient(
|
||||||
100
lib/view/page/ssh/virt_key_setting.dart
Normal file
100
lib/view/page/ssh/virt_key_setting.dart
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||||
|
import 'package:toolbox/core/extension/order.dart';
|
||||||
|
import 'package:toolbox/core/utils/ui.dart';
|
||||||
|
import 'package:toolbox/data/model/ssh/virtual_key.dart';
|
||||||
|
import 'package:toolbox/data/store/setting.dart';
|
||||||
|
import 'package:toolbox/locator.dart';
|
||||||
|
|
||||||
|
class SSHVirtKeySettingPage extends StatefulWidget {
|
||||||
|
const SSHVirtKeySettingPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_SSHVirtKeySettingPageState createState() => _SSHVirtKeySettingPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SSHVirtKeySettingPageState extends State<SSHVirtKeySettingPage> {
|
||||||
|
final _setting = locator<SettingStore>();
|
||||||
|
late S _s;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
super.didChangeDependencies();
|
||||||
|
_s = S.of(context)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text(_s.editVirtKeys),
|
||||||
|
),
|
||||||
|
body: _buildBody(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildBody() {
|
||||||
|
final keys = List<VirtKey>.from(_setting.sshVirtKeys.fetch()!);
|
||||||
|
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),
|
||||||
|
itemBuilder: (_, idx) {
|
||||||
|
final key = allKeys[idx];
|
||||||
|
return ListTile(
|
||||||
|
key: ValueKey(idx),
|
||||||
|
title: _buildTitle(key),
|
||||||
|
leading: const Icon(Icons.drag_handle, color: Colors.grey),
|
||||||
|
trailing: _buildCheckBox(keys, key, idx, idx < keys.length),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: allKeys.length,
|
||||||
|
onReorder: (o, n) {
|
||||||
|
if (o >= keys.length || n >= keys.length) {
|
||||||
|
showSnackBar(context, Text(_s.disabled));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
keys.moveById(keys[o], keys[n], _setting.sshVirtKeys);
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildTitle(VirtKey key) {
|
||||||
|
return key.icon == null
|
||||||
|
? Text(
|
||||||
|
key.text,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
)
|
||||||
|
: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(key.text),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Icon(key.icon),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildCheckBox(List<VirtKey> keys, VirtKey key, int idx, bool value) {
|
||||||
|
return Checkbox(
|
||||||
|
value: value,
|
||||||
|
onChanged: (val) {
|
||||||
|
if (val == null) return;
|
||||||
|
if (val) {
|
||||||
|
if (idx >= keys.length) {
|
||||||
|
keys.add(key);
|
||||||
|
} else {
|
||||||
|
keys.insert(idx - 1, key);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
keys.remove(key);
|
||||||
|
}
|
||||||
|
_setting.sshVirtKeys.put(keys);
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,9 +6,13 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <flutter_volume_controller/flutter_volume_controller_plugin.h>
|
||||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
|
g_autoptr(FlPluginRegistrar) flutter_volume_controller_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterVolumeControllerPlugin");
|
||||||
|
flutter_volume_controller_plugin_register_with_registrar(flutter_volume_controller_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||||
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
flutter_volume_controller
|
||||||
url_launcher_linux
|
url_launcher_linux
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,13 @@
|
|||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import flutter_volume_controller
|
||||||
import path_provider_foundation
|
import path_provider_foundation
|
||||||
import share_plus
|
import share_plus
|
||||||
import url_launcher_macos
|
import url_launcher_macos
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
FlutterVolumeControllerPlugin.register(with: registry.registrar(forPlugin: "FlutterVolumeControllerPlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
|
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
|
||||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
PODS:
|
PODS:
|
||||||
|
- flutter_volume_controller (0.0.1):
|
||||||
|
- FlutterMacOS
|
||||||
- FlutterMacOS (1.0.0)
|
- FlutterMacOS (1.0.0)
|
||||||
- path_provider_foundation (0.0.1):
|
- path_provider_foundation (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
@@ -9,12 +11,15 @@ PODS:
|
|||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
|
- flutter_volume_controller (from `Flutter/ephemeral/.symlinks/plugins/flutter_volume_controller/macos`)
|
||||||
- FlutterMacOS (from `Flutter/ephemeral`)
|
- FlutterMacOS (from `Flutter/ephemeral`)
|
||||||
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
|
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
|
||||||
- share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`)
|
- share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`)
|
||||||
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
|
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
|
flutter_volume_controller:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/flutter_volume_controller/macos
|
||||||
FlutterMacOS:
|
FlutterMacOS:
|
||||||
:path: Flutter/ephemeral
|
:path: Flutter/ephemeral
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
@@ -25,6 +30,7 @@ EXTERNAL SOURCES:
|
|||||||
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
|
flutter_volume_controller: 25d09126b0d695560f11c80b1311d5063fed882f
|
||||||
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
||||||
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
|
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
|
||||||
share_plus: 76dd39142738f7a68dd57b05093b5e8193f220f7
|
share_plus: 76dd39142738f7a68dd57b05093b5e8193f220f7
|
||||||
|
|||||||
@@ -377,6 +377,14 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
flutter_volume_controller:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_volume_controller
|
||||||
|
sha256: "5e7d1b63d051c881450a98155024219079a1cde0cf66ef895eb96dc9d8a7f670"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.6"
|
||||||
flutter_web_plugins:
|
flutter_web_plugins:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ dependencies:
|
|||||||
highlight: ^0.7.0
|
highlight: ^0.7.0
|
||||||
flutter_highlight: ^0.7.0
|
flutter_highlight: ^0.7.0
|
||||||
code_text_field: ^1.1.0
|
code_text_field: ^1.1.0
|
||||||
|
flutter_volume_controller: ^1.2.6
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_native_splash: ^2.1.6
|
flutter_native_splash: ^2.1.6
|
||||||
|
|||||||
@@ -6,10 +6,13 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <flutter_volume_controller/flutter_volume_controller_plugin_c_api.h>
|
||||||
#include <share_plus/share_plus_windows_plugin_c_api.h>
|
#include <share_plus/share_plus_windows_plugin_c_api.h>
|
||||||
#include <url_launcher_windows/url_launcher_windows.h>
|
#include <url_launcher_windows/url_launcher_windows.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
FlutterVolumeControllerPluginCApiRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("FlutterVolumeControllerPluginCApi"));
|
||||||
SharePlusWindowsPluginCApiRegisterWithRegistrar(
|
SharePlusWindowsPluginCApiRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
|
registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
|
||||||
UrlLauncherWindowsRegisterWithRegistrar(
|
UrlLauncherWindowsRegisterWithRegistrar(
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
flutter_volume_controller
|
||||||
share_plus
|
share_plus
|
||||||
url_launcher_windows
|
url_launcher_windows
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user