- add help for ssh virt keys
- rm unused lib
This commit is contained in:
lollipopkit
2023-07-29 16:24:47 +08:00
parent 1163f2e418
commit 7f4dcc1357
31 changed files with 159 additions and 172 deletions

View File

@@ -1334,6 +1334,18 @@ abstract class S {
/// **'See error'** /// **'See error'**
String get viewErr; String get viewErr;
/// No description provided for @virtKeyHelpClipboard.
///
/// In en, this message translates to:
/// **'Copy to the clipboard if terminal selected is not empty, otherwise paste the contents of the clipboard to the terminal.'**
String get virtKeyHelpClipboard;
/// No description provided for @virtKeyHelpSFTP.
///
/// In en, this message translates to:
/// **'Open current directory in SFTP.'**
String get virtKeyHelpSFTP;
/// No description provided for @waitConnection. /// No description provided for @waitConnection.
/// ///
/// In en, this message translates to: /// In en, this message translates to:

View File

@@ -666,6 +666,12 @@ class SDe extends S {
@override @override
String get viewErr => 'Fehler anzeigen'; String get viewErr => 'Fehler anzeigen';
@override
String get virtKeyHelpClipboard => 'In die Zwischenablage kopieren, wenn das ausgewählte Terminal nicht leer ist, andernfalls den Inhalt der Zwischenablage in das Terminal einfügen.';
@override
String get virtKeyHelpSFTP => 'Aktuelles Verzeichnis in SFTP öffnen.';
@override @override
String get waitConnection => 'Bitte warte, bis die Verbindung hergestellt wurde.'; String get waitConnection => 'Bitte warte, bis die Verbindung hergestellt wurde.';

View File

@@ -666,6 +666,12 @@ class SEn extends S {
@override @override
String get viewErr => 'See error'; String get viewErr => 'See error';
@override
String get virtKeyHelpClipboard => 'Copy to the clipboard if terminal selected is not empty, otherwise paste the contents of the clipboard to the terminal.';
@override
String get virtKeyHelpSFTP => 'Open current directory in SFTP.';
@override @override
String get waitConnection => 'Please wait for the connection to be established.'; String get waitConnection => 'Please wait for the connection to be established.';

View File

@@ -666,6 +666,12 @@ class SId extends S {
@override @override
String get viewErr => 'Lihat kesalahan'; String get viewErr => 'Lihat kesalahan';
@override
String get virtKeyHelpClipboard => 'Salin ke clipboard jika terminal yang dipilih tidak kosong, jika tidak, tempel isi clipboard ke terminal.';
@override
String get virtKeyHelpSFTP => 'Buka direktori saat ini di SFTP.';
@override @override
String get waitConnection => 'Harap tunggu koneksi akan dibuat.'; String get waitConnection => 'Harap tunggu koneksi akan dibuat.';

View File

@@ -666,6 +666,12 @@ class SZh extends S {
@override @override
String get viewErr => '查看错误'; String get viewErr => '查看错误';
@override
String get virtKeyHelpClipboard => '如果终端有选中字符,则复制选中字符至剪切板,否则粘贴剪切板内容至终端。';
@override
String get virtKeyHelpSFTP => '在 SFTP 中打开当前路径。';
@override @override
String get waitConnection => '请等待连接建立'; String get waitConnection => '请等待连接建立';
@@ -1342,6 +1348,12 @@ class SZhTw extends SZh {
@override @override
String get viewErr => '查看錯誤'; String get viewErr => '查看錯誤';
@override
String get virtKeyHelpClipboard => '如果終端有選中字符,則復製選中字符至剪切板,否則粘貼剪切板內容至終端。';
@override
String get virtKeyHelpSFTP => '在 SFTP 中打開當前路徑。';
@override @override
String get waitConnection => '請等待連接建立'; String get waitConnection => '請等待連接建立';

View File

@@ -31,7 +31,7 @@ Especially thanks to <a href="https://github.com/TerminalStudio/dartssh2">dartss
- [x] `Status` charts - [x] `Status` charts
- [x] `Code editor` - [x] `Code editor`
- [x] `Ping` and etc. - [x] `Ping` and etc.
- [x] Localization ( English, 简体中文, Deutsch, 繁體中文, Indonesian. [How to contribute?](#l10n-guide)) - [x] Localization ( English, 简体中文, Deutsch, 繁體中文, Indonesian. [l10n guide](#l10n-guide) )
- [x] Desktop support - [x] Desktop support
@@ -86,7 +86,10 @@ Full Support| Android / iOS / macOS
Support, but not tested| Windows / Linux Support, but not tested| Windows / Linux
## l10n guide ## 🧱 Contribution
**Any positive contribution is welcome**.
10 iOS app redemption codes will be given away for the first time you participate in the contribution. This is the only thing I can do to thank you. :)
### l10n guide
1. Fork this repo and clone forked repo to your local machine. 1. Fork this repo and clone forked repo to your local machine.
2. Create `arb` file in `lib/l10n/` directory 2. Create `arb` file in `lib/l10n/` directory
- File name should be `intl_XX.arb`, where `XX` is the language code. Such as `intl_en.arb` for English and `intl_zh.arb` for Chinese. - File name should be `intl_XX.arb`, where `XX` is the language code. Such as `intl_en.arb` for English and `intl_zh.arb` for Chinese.

View File

@@ -31,7 +31,7 @@
- [x] 状态图表 - [x] 状态图表
- [x] 代码编辑器 - [x] 代码编辑器
- [x] `Ping` 和 更多 - [x] `Ping` 和 更多
- [x] 本地化 ( English, 简体中文, Deutsch, 繁體中文, Indonesian。 [如何贡献?](#l10n-guide)) - [x] 本地化 ( English, 简体中文, Deutsch, 繁體中文, Indonesian。 [如何贡献?](#l10n))
- [x] 桌面端支持 - [x] 桌面端支持
@@ -85,8 +85,11 @@
完整支持 | Android / iOS / macOS 完整支持 | Android / iOS / macOS
可能支持,未测试 | Windows / Linux 可能支持,未测试 | Windows / Linux
## 🧱 贡献
**任何正面的贡献都欢迎**.
第一次参与贡献,会赠送 10 份 iOS App 兑换码。这是我唯一能送的。你可以同来送给其他人。:)
## l10n ### l10n
1. Fork 本项目,并 Clone 你 Fork 的项目至你的电脑 1. Fork 本项目,并 Clone 你 Fork 的项目至你的电脑
2.`lib/l10n/` 文件夹内创建 `.arb` 本地化文件 2.`lib/l10n/` 文件夹内创建 `.arb` 本地化文件
- 文件名应该类似 `intl_XX.arb`, `XX` 是语言标识码。 例如 `intl_en.arb` 是给英语的, `intl_zh.arb` 是给中文的 - 文件名应该类似 `intl_XX.arb`, `XX` 是语言标识码。 例如 `intl_en.arb` 是给英语的, `intl_zh.arb` 是给中文的

View File

@@ -470,7 +470,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 396; CURRENT_PROJECT_VERSION = 397;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -478,7 +478,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.396; MARKETING_VERSION = 1.0.397;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -602,7 +602,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 396; CURRENT_PROJECT_VERSION = 397;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -610,7 +610,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.396; MARKETING_VERSION = 1.0.397;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -628,7 +628,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 396; CURRENT_PROJECT_VERSION = 397;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -636,7 +636,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.396; MARKETING_VERSION = 1.0.397;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -657,7 +657,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 396; CURRENT_PROJECT_VERSION = 397;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -670,7 +670,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.396; MARKETING_VERSION = 1.0.397;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
@@ -696,7 +696,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 396; CURRENT_PROJECT_VERSION = 397;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -709,7 +709,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.396; MARKETING_VERSION = 1.0.397;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@@ -732,7 +732,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 396; CURRENT_PROJECT_VERSION = 397;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -745,7 +745,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.396; MARKETING_VERSION = 1.0.397;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";

View File

@@ -17,7 +17,7 @@ class TryLimiter {
return true; return true;
} }
void resetTryTimes(String id) { void reset(String id) {
_triedTimes[id] = 0; _triedTimes[id] = 0;
} }

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
import 'package:xterm/core.dart'; import 'package:xterm/core.dart';
@@ -17,7 +18,7 @@ enum VirtKey {
@HiveField(4) @HiveField(4)
end, end,
@HiveField(5) @HiveField(5)
file, sftp,
@HiveField(6) @HiveField(6)
snippet, snippet,
@HiveField(7) @HiveField(7)
@@ -31,7 +32,7 @@ enum VirtKey {
@HiveField(11) @HiveField(11)
right, right,
@HiveField(12) @HiveField(12)
paste, clipboard,
@HiveField(13) @HiveField(13)
ime, ime,
@HiveField(14) @HiveField(14)
@@ -94,11 +95,11 @@ enum VirtKey {
return Icons.arrow_downward; return Icons.arrow_downward;
case VirtKey.right: case VirtKey.right:
return Icons.arrow_forward; return Icons.arrow_forward;
case VirtKey.file: case VirtKey.sftp:
return Icons.file_open; return Icons.file_open;
case VirtKey.snippet: case VirtKey.snippet:
return Icons.code; return Icons.code;
case VirtKey.paste: case VirtKey.clipboard:
return Icons.paste; return Icons.paste;
case VirtKey.ime: case VirtKey.ime:
return Icons.keyboard_hide; return Icons.keyboard_hide;
@@ -112,12 +113,12 @@ enum VirtKey {
// and make sure all [VirtualKeyFunc] are handled // and make sure all [VirtualKeyFunc] are handled
VirtualKeyFunc? get func { VirtualKeyFunc? get func {
switch (this) { switch (this) {
case VirtKey.file: case VirtKey.sftp:
return VirtualKeyFunc.file; return VirtualKeyFunc.file;
case VirtKey.snippet: case VirtKey.snippet:
return VirtualKeyFunc.snippet; return VirtualKeyFunc.snippet;
case VirtKey.paste: case VirtKey.clipboard:
return VirtualKeyFunc.paste; return VirtualKeyFunc.clipboard;
case VirtKey.ime: case VirtKey.ime:
return VirtualKeyFunc.toggleIME; return VirtualKeyFunc.toggleIME;
default: default:
@@ -146,6 +147,17 @@ enum VirtKey {
return false; 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 }

View File

@@ -24,7 +24,7 @@ class VirtKeyAdapter extends TypeAdapter<VirtKey> {
case 4: case 4:
return VirtKey.end; return VirtKey.end;
case 5: case 5:
return VirtKey.file; return VirtKey.sftp;
case 6: case 6:
return VirtKey.snippet; return VirtKey.snippet;
case 7: case 7:
@@ -38,7 +38,7 @@ class VirtKeyAdapter extends TypeAdapter<VirtKey> {
case 11: case 11:
return VirtKey.right; return VirtKey.right;
case 12: case 12:
return VirtKey.paste; return VirtKey.clipboard;
case 13: case 13:
return VirtKey.ime; return VirtKey.ime;
case 14: case 14:
@@ -68,7 +68,7 @@ class VirtKeyAdapter extends TypeAdapter<VirtKey> {
case VirtKey.end: case VirtKey.end:
writer.writeByte(4); writer.writeByte(4);
break; break;
case VirtKey.file: case VirtKey.sftp:
writer.writeByte(5); writer.writeByte(5);
break; break;
case VirtKey.snippet: case VirtKey.snippet:
@@ -89,7 +89,7 @@ class VirtKeyAdapter extends TypeAdapter<VirtKey> {
case VirtKey.right: case VirtKey.right:
writer.writeByte(11); writer.writeByte(11);
break; break;
case VirtKey.paste: case VirtKey.clipboard:
writer.writeByte(12); writer.writeByte(12);
break; break;
case VirtKey.ime: case VirtKey.ime:

View File

@@ -101,7 +101,7 @@ class ServerProvider extends BusyProvider {
await Future.wait(_servers.values.map((s) async { await Future.wait(_servers.values.map((s) async {
if (onlyFailed) { if (onlyFailed) {
if (s.state != ServerState.failed) return; if (s.state != ServerState.failed) return;
_limiter.resetTryTimes(s.spi.id); _limiter.reset(s.spi.id);
} }
return await _getData(s.spi); return await _getData(s.spi);
})); }));
@@ -109,8 +109,8 @@ class ServerProvider extends BusyProvider {
Future<void> startAutoRefresh() async { Future<void> startAutoRefresh() async {
final duration = _settingStore.serverStatusUpdateInterval.fetch()!; final duration = _settingStore.serverStatusUpdateInterval.fetch()!;
if (duration == 0) return;
stopAutoRefresh(); stopAutoRefresh();
if (duration == 0) return;
_timer = Timer.periodic(Duration(seconds: duration), (_) async { _timer = Timer.periodic(Duration(seconds: duration), (_) async {
await refreshData(); await refreshData();
}); });
@@ -240,7 +240,7 @@ class ServerProvider extends BusyProvider {
throw Exception(writeResult); throw Exception(writeResult);
} }
// reset try times if connected successfully // reset try times if connected successfully
_limiter.resetTryTimes(sid); _limiter.reset(sid);
} }
if (s.client == null) return; if (s.client == null) return;

View File

@@ -2,8 +2,8 @@
class BuildData { class BuildData {
static const String name = "ServerBox"; 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 engine = "3.10.6";
static const String buildAt = "2023-07-28 19:15:52.944462"; static const String buildAt = "2023-07-28 20:51:35.807892";
static const int modifications = 5; static const int modifications = 6;
} }

View File

@@ -28,14 +28,14 @@ const defaultSSHVirtKeys = [
VirtKey.home, VirtKey.home,
VirtKey.up, VirtKey.up,
VirtKey.end, VirtKey.end,
VirtKey.file, VirtKey.sftp,
VirtKey.snippet, VirtKey.snippet,
VirtKey.tab, VirtKey.tab,
VirtKey.ctrl, VirtKey.ctrl,
VirtKey.left, VirtKey.left,
VirtKey.down, VirtKey.down,
VirtKey.right, VirtKey.right,
VirtKey.paste, VirtKey.clipboard,
VirtKey.ime, VirtKey.ime,
]; ];

View File

@@ -206,6 +206,8 @@
"versionUnknownUpdate": "Aktuell: v1.0.{build}", "versionUnknownUpdate": "Aktuell: v1.0.{build}",
"versionUpdated": "v1.0.{build} ist bereits die neueste Version", "versionUpdated": "v1.0.{build} ist bereits die neueste Version",
"viewErr": "Fehler anzeigen", "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.", "waitConnection": "Bitte warte, bis die Verbindung hergestellt wurde.",
"whenOpenApp": "Beim Öffnen der App", "whenOpenApp": "Beim Öffnen der App",
"willTakEeffectImmediately": "Wird sofort angewendet" "willTakEeffectImmediately": "Wird sofort angewendet"

View File

@@ -206,6 +206,8 @@
"versionUnknownUpdate": "Current: v1.0.{build}", "versionUnknownUpdate": "Current: v1.0.{build}",
"versionUpdated": "Current: v1.0.{build}, is up to date", "versionUpdated": "Current: v1.0.{build}, is up to date",
"viewErr": "See error", "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.", "waitConnection": "Please wait for the connection to be established.",
"whenOpenApp": "When opening the app", "whenOpenApp": "When opening the app",
"willTakEeffectImmediately": "Will take effect immediately" "willTakEeffectImmediately": "Will take effect immediately"

View File

@@ -45,7 +45,7 @@
"dockerEditHost": "Edit Docker_host", "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.", "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", "dockerImagesFmt": "{count} gambar",
"dockerNotInstalled": "Docker tidak terpasang", "dockerNotInstalled": "Docker tidak terpasang",
"dockerStatusRunningAndStoppedFmt": "{runningCount} running, {stoppedCount} container stopped.", "dockerStatusRunningAndStoppedFmt": "{runningCount} running, {stoppedCount} container stopped.",
"dockerStatusRunningFmt": "{count} wadah berjalan.", "dockerStatusRunningFmt": "{count} wadah berjalan.",
"download": "Unduh", "download": "Unduh",
@@ -206,6 +206,8 @@
"versionUnknownUpdate": "Saat ini: v1.0.{build}", "versionUnknownUpdate": "Saat ini: v1.0.{build}",
"versionUpdated": "Saat ini: v1.0.{build}, mutakhir", "versionUpdated": "Saat ini: v1.0.{build}, mutakhir",
"viewErr": "Lihat kesalahan", "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.", "waitConnection": "Harap tunggu koneksi akan dibuat.",
"whenOpenApp": "Saat membuka aplikasi", "whenOpenApp": "Saat membuka aplikasi",
"willTakEeffectImmediately": "Akan segera berlaku" "willTakEeffectImmediately": "Akan segera berlaku"

View File

@@ -206,6 +206,8 @@
"versionUnknownUpdate": "当前v1.0.{build}", "versionUnknownUpdate": "当前v1.0.{build}",
"versionUpdated": "当前v1.0.{build}, 已是最新版本", "versionUpdated": "当前v1.0.{build}, 已是最新版本",
"viewErr": "查看错误", "viewErr": "查看错误",
"virtKeyHelpClipboard": "如果终端有选中字符,则复制选中字符至剪切板,否则粘贴剪切板内容至终端。",
"virtKeyHelpSFTP": "在 SFTP 中打开当前路径。",
"waitConnection": "请等待连接建立", "waitConnection": "请等待连接建立",
"whenOpenApp": "当打开 App 时", "whenOpenApp": "当打开 App 时",
"willTakEeffectImmediately": "更改将会立即生效" "willTakEeffectImmediately": "更改将会立即生效"

View File

@@ -206,6 +206,8 @@
"versionUnknownUpdate": "當前v1.0.{build}", "versionUnknownUpdate": "當前v1.0.{build}",
"versionUpdated": "當前v1.0.{build}, 已是最新版本", "versionUpdated": "當前v1.0.{build}, 已是最新版本",
"viewErr": "查看錯誤", "viewErr": "查看錯誤",
"virtKeyHelpClipboard": "如果終端有選中字符,則復製選中字符至剪切板,否則粘貼剪切板內容至終端。",
"virtKeyHelpSFTP": "在 SFTP 中打開當前路徑。",
"waitConnection": "請等待連接建立", "waitConnection": "請等待連接建立",
"whenOpenApp": "當打開 App 時", "whenOpenApp": "當打開 App 時",
"willTakEeffectImmediately": "更改將會立即生效" "willTakEeffectImmediately": "更改將會立即生效"

View File

@@ -76,18 +76,6 @@ class _SFTPDownloadedPageState extends State<SFTPDownloadedPage> {
bottomNavigationBar: SafeArea( bottomNavigationBar: SafeArea(
child: _buildPath(), 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 dir = Directory(_path!.path);
final files = dir.listSync(); final files = dir.listSync();
final canGoBack = _path!.path != _prefixPath;
return ListView.builder( return ListView.builder(
itemCount: files.length, itemCount: canGoBack ? files.length + 1 : files.length,
padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 7), padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 7),
itemBuilder: (context, index) { 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 file = files[index];
var fileName = file.path.split('/').last; var fileName = file.path.split('/').last;
var stat = file.statSync(); var stat = file.statSync();

View File

@@ -39,11 +39,9 @@ class _SSHPageState extends State<SSHPage> {
final _setting = locator<SettingStore>(); final _setting = locator<SettingStore>();
late final _terminal = Terminal(inputHandler: _keyboard); late final _terminal = Terminal(inputHandler: _keyboard);
final TerminalController _terminalController = TerminalController(); final TerminalController _terminalController = TerminalController();
final ContextMenuController _menuController = ContextMenuController();
final List<List<VirtKey>> _virtKeysList = []; final List<List<VirtKey>> _virtKeysList = [];
late MediaQueryData _media; late MediaQueryData _media;
late TextStyle _menuTextStyle;
late S _s; late S _s;
late TerminalStyle _terminalStyle; late TerminalStyle _terminalStyle;
late TerminalTheme _terminalTheme; late TerminalTheme _terminalTheme;
@@ -75,7 +73,6 @@ class _SSHPageState extends State<SSHPage> {
super.didChangeDependencies(); super.didChangeDependencies();
_isDark = isDarkMode(context); _isDark = isDarkMode(context);
_media = MediaQuery.of(context); _media = MediaQuery.of(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 // Calculate virtkey width / height
@@ -118,8 +115,7 @@ class _SSHPageState extends State<SSHPage> {
textStyle: _terminalStyle, textStyle: _terminalStyle,
theme: _terminalTheme, theme: _terminalTheme,
deleteDetection: isIOS, deleteDetection: isIOS,
onTapUp: _onTapUp, autofocus: true,
autoFocus: true,
keyboardAppearance: _isDark ? Brightness.dark : Brightness.light, keyboardAppearance: _isDark ? Brightness.dark : Brightness.light,
), ),
); );
@@ -231,13 +227,12 @@ class _SSHPageState extends State<SSHPage> {
case VirtualKeyFunc.backspace: case VirtualKeyFunc.backspace:
_terminal.keyInput(TerminalKey.backspace); _terminal.keyInput(TerminalKey.backspace);
break; break;
case VirtualKeyFunc.paste: case VirtualKeyFunc.clipboard:
_paste();
break;
case VirtualKeyFunc.copy:
final selected = terminalSelected; final selected = terminalSelected;
if (selected != null) { if (selected != null) {
copy2Clipboard(selected); copy2Clipboard(selected);
} else {
_paste();
} }
break; break;
case VirtualKeyFunc.snippet: case VirtualKeyFunc.snippet:
@@ -290,58 +285,12 @@ class _SSHPageState extends State<SSHPage> {
return _terminal.buffer.getText(range); 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) { void _write(String p0) {
_terminal.write('$p0\r\n'); _terminal.write('$p0\r\n');
} }
void _initVirtKeys() { void _initVirtKeys() {
final virtKeys = _setting.sshVirtKeys.fetch()!; final virtKeys = List<VirtKey>.from(_setting.sshVirtKeys.fetchRaw());
for (int len = 0; len < virtKeys.length; len += 7) { for (int len = 0; len < virtKeys.length; len += 7) {
if (len + 7 > virtKeys.length) { if (len + 7 > virtKeys.length) {

View File

@@ -1,12 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.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/extension/order.dart';
import 'package:toolbox/core/utils/platform.dart'; import 'package:toolbox/core/utils/platform.dart';
import 'package:toolbox/core/utils/ui.dart'; import 'package:toolbox/core/utils/ui.dart';
import 'package:toolbox/data/model/ssh/virtual_key.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/data/store/setting.dart';
import 'package:toolbox/locator.dart'; import 'package:toolbox/locator.dart';
import 'package:toolbox/view/widget/round_rect_card.dart';
class SSHVirtKeySettingPage extends StatefulWidget { class SSHVirtKeySettingPage extends StatefulWidget {
const SSHVirtKeySettingPage({Key? key}) : super(key: key); 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 disabled = VirtKey.values.where((e) => !keys.contains(e)).toList();
final allKeys = [...keys, ...disabled]; final allKeys = [...keys, ...disabled];
return ReorderableListView.builder( return ReorderableListView.builder(
padding: const EdgeInsets.fromLTRB(11, 3, 0, 3), padding: const EdgeInsets.all(7),
itemBuilder: (_, idx) { itemBuilder: (_, idx) {
final key = allKeys[idx]; final key = allKeys[idx];
return ListTile( final help = key.help(_s);
key: ValueKey(idx), return RoundRectCard(
title: _buildTitle(key), key: ValueKey(idx),
leading: _buildCheckBox(keys, key, idx, idx < keys.length), ListTile(
trailing: isDesktop title: _buildTitle(key),
? nil subtitle: help == null ? null : Text(help, style: grey),
: const Icon(Icons.drag_handle, color: Colors.grey), leading: _buildCheckBox(keys, key, idx, idx < keys.length),
); trailing: isDesktop ? null : const Icon(Icons.drag_handle),
));
}, },
itemCount: allKeys.length, itemCount: allKeys.length,
onReorder: (o, n) { onReorder: (o, n) {
@@ -70,12 +72,8 @@ class _SSHVirtKeySettingPageState extends State<SSHVirtKeySettingPage> {
Widget _buildTitle(VirtKey key) { Widget _buildTitle(VirtKey key) {
return key.icon == null return key.icon == null
? Text( ? Text(key.text)
key.text,
textAlign: TextAlign.center,
)
: Row( : Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text(key.text), Text(key.text),
const SizedBox(width: 10), const SizedBox(width: 10),

View File

@@ -6,13 +6,9 @@
#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);

View File

@@ -3,7 +3,6 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
flutter_volume_controller
url_launcher_linux url_launcher_linux
) )

View File

@@ -5,14 +5,12 @@
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 shared_preferences_foundation import shared_preferences_foundation
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"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))

View File

@@ -475,9 +475,9 @@
baseConfigurationReference = C1C758C41C4E208965A68933 /* Pods-RunnerTests.debug.xcconfig */; baseConfigurationReference = C1C758C41C4E208965A68933 /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 396; CURRENT_PROJECT_VERSION = 397;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0.396; MARKETING_VERSION = 1.0.397;
PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@@ -490,9 +490,9 @@
baseConfigurationReference = 15AF97DF993E8968098D6EBE /* Pods-RunnerTests.release.xcconfig */; baseConfigurationReference = 15AF97DF993E8968098D6EBE /* Pods-RunnerTests.release.xcconfig */;
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 396; CURRENT_PROJECT_VERSION = 397;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0.396; MARKETING_VERSION = 1.0.397;
PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@@ -505,9 +505,9 @@
baseConfigurationReference = 7CFA7DE7FABA75685DFB6948 /* Pods-RunnerTests.profile.xcconfig */; baseConfigurationReference = 7CFA7DE7FABA75685DFB6948 /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 396; CURRENT_PROJECT_VERSION = 397;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0.396; MARKETING_VERSION = 1.0.397;
PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;

View File

@@ -146,10 +146,9 @@ Future<void> flutterBuildAndroid() async {
} }
Future<void> scp2CDN() async { Future<void> scp2CDN() async {
final result = await Process.run('scp', [ print('scp2CDN...');
apkPath, final result = await Process.run(
'custcdn:/usr/share/caddy/uploads/${appName}_${build}_Arm64.apk' 'scp', [apkPath, 'hk:/var/www/res/serverbox/apks/$build.apk']);
]);
print(result.stdout); print(result.stdout);
if (result.exitCode != 0) { if (result.exitCode != 0) {
print(result.stderr); print(result.stderr);

View File

@@ -361,14 +361,6 @@ 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
@@ -1070,12 +1062,11 @@ packages:
xterm: xterm:
dependency: "direct main" dependency: "direct main"
description: description:
path: "." name: xterm
ref: master sha256: "6a02b15d03152b8186e12790902ff28c8a932fc441e89fa7255a7491661a8e69"
resolved-ref: e945750b97a2f875befa37e0c483bc3f51e215b2 url: "https://pub.dev"
url: "https://github.com/lollipopkit/xterm.dart" source: hosted
source: git version: "3.5.0"
version: "3.6.1-pre"
yaml: yaml:
dependency: transitive dependency: transitive
description: description:
@@ -1084,14 +1075,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.2" version: "3.1.2"
zmodem:
dependency: transitive
description:
name: zmodem
sha256: "3b7e5b29f3a7d8aee472029b05165a68438eff2f3f7766edf13daba1e297adbf"
url: "https://pub.dev"
source: hosted
version: "0.0.6"
sdks: sdks:
dart: ">=3.0.2 <4.0.0" dart: ">=3.0.2 <4.0.0"
flutter: ">=3.3.0" flutter: ">=3.3.0"

View File

@@ -53,18 +53,17 @@ dependencies:
easy_isolate: ^1.3.0 easy_isolate: ^1.3.0
share_plus: ^7.0.2 share_plus: ^7.0.2
intl: ^0.18.0 intl: ^0.18.0
# xterm: ^3.4.1 xterm: ^3.5.0
xterm: # xterm:
#path: ../xterm.dart # #path: ../xterm.dart
git: # git:
ref: master # ref: master
url: https://github.com/lollipopkit/xterm.dart # url: https://github.com/lollipopkit/xterm.dart
file_picker: ^5.3.2 file_picker: ^5.3.2
plain_notification_token: ^0.0.4 plain_notification_token: ^0.0.4
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
nil: ^1.1.1 nil: ^1.1.1
shared_preferences: ^2.1.1 shared_preferences: ^2.1.1

View File

@@ -6,13 +6,10 @@
#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(

View File

@@ -3,7 +3,6 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
flutter_volume_controller
share_plus share_plus
url_launcher_windows url_launcher_windows
) )