diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n.dart b/.dart_tool/flutter_gen/gen_l10n/l10n.dart index a18f7d87..2ae1ab9d 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n.dart @@ -202,6 +202,12 @@ abstract class S { /// **'Auto connect'** String get autoConnect; + /// No description provided for @autoRun. + /// + /// In en, this message translates to: + /// **'Automatic Run'** + String get autoRun; + /// No description provided for @autoUpdateHomeWidget. /// /// In en, this message translates to: @@ -1342,18 +1348,18 @@ abstract class S { /// **'Use `rm -r` to delete a folder in SFTP.'** String get sftpRmrDirSummary; - /// No description provided for @sftpShowFoldersFirst. - /// - /// In en, this message translates to: - /// **'Disply folders first'** - String get sftpShowFoldersFirst; - /// No description provided for @sftpSSHConnected. /// /// In en, this message translates to: /// **'SFTP Connected'** String get sftpSSHConnected; + /// No description provided for @sftpShowFoldersFirst. + /// + /// In en, this message translates to: + /// **'Disply folders first'** + String get sftpShowFoldersFirst; + /// No description provided for @showDistLogo. /// /// In en, this message translates to: diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart index 4a721363..cd983a6e 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart @@ -57,6 +57,9 @@ class SDe extends S { @override String get autoConnect => 'Automatisch verbinden'; + @override + String get autoRun => 'Automatischer Start'; + @override String get autoUpdateHomeWidget => 'Home-Widget automatisch aktualisieren'; @@ -652,10 +655,10 @@ class SDe extends S { String get sftpRmrDirSummary => 'Verwenden Sie \"rm -r\", um das Verzeichnis in SFTP zu löschen.'; @override - String get sftpShowFoldersFirst => 'Ordner zuerst anzeigen'; + String get sftpSSHConnected => 'SFTP Verbunden'; @override - String get sftpSSHConnected => 'SFTP Verbunden'; + String get sftpShowFoldersFirst => 'Ordner zuerst anzeigen'; @override String get showDistLogo => 'Distributionslogo anzeigen'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart index abdf03d9..4d343a5a 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart @@ -57,6 +57,9 @@ class SEn extends S { @override String get autoConnect => 'Auto connect'; + @override + String get autoRun => 'Automatic Run'; + @override String get autoUpdateHomeWidget => 'Auto update home widget'; @@ -652,10 +655,10 @@ class SEn extends S { String get sftpRmrDirSummary => 'Use `rm -r` to delete a folder in SFTP.'; @override - String get sftpShowFoldersFirst => 'Disply folders first'; + String get sftpSSHConnected => 'SFTP Connected'; @override - String get sftpSSHConnected => 'SFTP Connected'; + String get sftpShowFoldersFirst => 'Disply folders first'; @override String get showDistLogo => 'Show distribution logo'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_fr.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_fr.dart index 7f64e41f..42aab0ee 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_fr.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_fr.dart @@ -57,6 +57,9 @@ class SFr extends S { @override String get autoConnect => 'Connexion automatique'; + @override + String get autoRun => 'Exécution automatique'; + @override String get autoUpdateHomeWidget => 'Mise à jour automatique du widget d\'accueil'; @@ -652,10 +655,10 @@ class SFr extends S { String get sftpRmrDirSummary => 'Utilisez `rm -r` pour supprimer un dossier dans SFTP.'; @override - String get sftpShowFoldersFirst => 'Dossiers d\'abord lors du tri'; + String get sftpSSHConnected => 'SFTP connecté'; @override - String get sftpSSHConnected => 'SFTP connecté'; + String get sftpShowFoldersFirst => 'Dossiers d\'abord lors du tri'; @override String get showDistLogo => 'Afficher le logo de la distribution'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_id.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_id.dart index 1c74e9f7..6e55c4e1 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_id.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_id.dart @@ -57,6 +57,9 @@ class SId extends S { @override String get autoConnect => 'Hubungkan otomatis'; + @override + String get autoRun => 'Berjalan Otomatis'; + @override String get autoUpdateHomeWidget => 'Widget Rumah Pembaruan Otomatis'; @@ -652,10 +655,10 @@ class SId extends S { String get sftpRmrDirSummary => 'Gunakan `rm -r` untuk menghapus dir di SFTP'; @override - String get sftpShowFoldersFirst => 'Folder ditampilkan lebih dulu'; + String get sftpSSHConnected => 'Sftp terhubung'; @override - String get sftpSSHConnected => 'Sftp terhubung'; + String get sftpShowFoldersFirst => 'Folder ditampilkan lebih dulu'; @override String get showDistLogo => 'Tampilkan logo distribusi'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart index ec5d0427..2016ca19 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart @@ -57,6 +57,9 @@ class SZh extends S { @override String get autoConnect => '自动连接'; + @override + String get autoRun => '自动运行'; + @override String get autoUpdateHomeWidget => '自动更新桌面小部件'; @@ -652,10 +655,10 @@ class SZh extends S { String get sftpRmrDirSummary => '在 SFTP 中使用 `rm -r` 来删除文件夹'; @override - String get sftpShowFoldersFirst => '排序时文件夹显示在前'; + String get sftpSSHConnected => 'SFTP 已连接...'; @override - String get sftpSSHConnected => 'SFTP 已连接...'; + String get sftpShowFoldersFirst => '排序时文件夹显示在前'; @override String get showDistLogo => '显示发行版 Logo'; @@ -911,6 +914,9 @@ class SZhTw extends SZh { @override String get autoConnect => '自動連接'; + @override + String get autoRun => '自動運行'; + @override String get autoUpdateHomeWidget => '自動更新桌面小部件'; @@ -1506,10 +1512,10 @@ class SZhTw extends SZh { String get sftpRmrDirSummary => '在 SFTP 中使用 `rm -r` 來刪除文件夾'; @override - String get sftpShowFoldersFirst => '排序時文件夾顯示在前'; + String get sftpSSHConnected => 'SFTP 已連接...'; @override - String get sftpSSHConnected => 'SFTP 已連接...'; + String get sftpShowFoldersFirst => '排序時文件夾顯示在前'; @override String get showDistLogo => '顯示發行版 Logo'; diff --git a/android/app/build.gradle b/android/app/build.gradle index f12f8d0a..993c94ab 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -48,7 +48,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.lollipopkit.flutter_server_box" + applicationId "tech.lolli.toolbox" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. minSdkVersion flutter.minSdkVersion diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 589045a9..82355151 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - countly_flutter (23.8.4): + - countly_flutter (23.12.1): - Flutter - file_picker (0.0.1): - Flutter @@ -76,19 +76,19 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/watch_connectivity/ios" SPEC CHECKSUMS: - countly_flutter: d880b352f212d4f6453a87c85f0455f3b4b9c611 + countly_flutter: 0b87be283b3ecef341b5f8d45ff97dd33ee966b9 file_picker: 880e54928ebe4aa405aaf4577f29a76a078341c6 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 flutter_background_service_ios: e30e0d3ee69e4cee66272d0c78eacd48c2e94aac flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef icloud_storage: d9ac7a33ced81df08ba7ea1bf3099cc0ee58f60a - local_auth_ios: c6cf091ded637a88f24f86a8875d8b0f526e2605 - path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 + local_auth_ios: 5046a18c018dd973247a0564496c8898dbb5adf9 + path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c plain_notification_token: b36467dc91939a7b6754267c701bbaca14996ee1 r_upgrade: 44d715c61914cce3d01ea225abffe894fd51c114 share_plus: c3fef564749587fc939ef86ffb283ceac0baf9f5 - shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126 - url_launcher_ios: bf5ce03e0e2088bad9cc378ea97fa0ed5b49673b + shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695 + url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812 watch_connectivity: 715eb484685e05846eab74795348a44bb2809b82 PODFILE CHECKSUM: ec6ef69056f066e8b21a3391082f23b5ad2d37f8 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 8bf3c921..8ca5900e 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -318,7 +318,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 1430; - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -586,7 +586,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 746; + CURRENT_PROJECT_VERSION = 761; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -596,7 +596,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.746; + MARKETING_VERSION = 1.0.761; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -720,7 +720,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 746; + CURRENT_PROJECT_VERSION = 761; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -730,7 +730,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.746; + MARKETING_VERSION = 1.0.761; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -748,7 +748,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 746; + CURRENT_PROJECT_VERSION = 761; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -758,7 +758,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.746; + MARKETING_VERSION = 1.0.761; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -779,7 +779,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 746; + CURRENT_PROJECT_VERSION = 761; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -792,7 +792,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.746; + MARKETING_VERSION = 1.0.761; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; @@ -818,7 +818,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 746; + CURRENT_PROJECT_VERSION = 761; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -831,7 +831,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.746; + MARKETING_VERSION = 1.0.761; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -854,7 +854,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 746; + CURRENT_PROJECT_VERSION = 761; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -867,7 +867,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.746; + MARKETING_VERSION = 1.0.761; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -890,7 +890,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 746; + CURRENT_PROJECT_VERSION = 761; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -902,7 +902,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.746; + MARKETING_VERSION = 1.0.761; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; @@ -931,7 +931,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 746; + CURRENT_PROJECT_VERSION = 761; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -943,7 +943,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.746; + MARKETING_VERSION = 1.0.761; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; @@ -969,7 +969,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 746; + CURRENT_PROJECT_VERSION = 761; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -981,7 +981,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.746; + MARKETING_VERSION = 1.0.761; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index a6b826db..5e31d3d3 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ ?> showPickDialog({ required List items, - required String Function(T) name, + String Function(T)? name, bool multi = true, + List? initial, + bool clearable = false, + List? actions, }) async { - var vals = []; + var vals = initial ?? []; final sure = await showRoundDialog( title: Text(l10n.choose), - child: Choice( - onChanged: (value) => vals = value, - multiple: multi, - clearable: true, - builder: (state, _) { - return Wrap( - children: List.generate( - items.length, - (index) { - final item = items[index]; - if (item == null) return UIs.placeholder; - return ChoiceChipX( - label: name(item), - state: state, - value: item, - ); - }, - ), - ); - }, + child: SingleChildScrollView( + child: Choice( + onChanged: (value) => vals = value, + multiple: multi, + clearable: clearable, + value: vals, + builder: (state, _) { + return Wrap( + children: List.generate( + items.length, + (index) { + final item = items[index]; + if (item == null) return UIs.placeholder; + return ChoiceChipX( + label: name?.call(item) ?? item.toString(), + state: state, + value: item, + ); + }, + ), + ); + }, + ), ), actions: [ + if (actions != null) ...actions, TextButton( onPressed: () => pop(true), child: Text(l10n.ok), @@ -95,12 +102,17 @@ extension DialogX on BuildContext { Future showPickSingleDialog({ required List items, - required String Function(T) name, + String Function(T)? name, + T? initial, + bool clearable = false, + List? actions, }) async { final vals = await showPickDialog( items: items, name: name, multi: false, + initial: initial == null ? null : [initial], + actions: actions, ); if (vals != null && vals.isNotEmpty) { return vals.first; diff --git a/lib/core/extension/ssh_client.dart b/lib/core/extension/ssh_client.dart index 42d66c33..49e76753 100644 --- a/lib/core/extension/ssh_client.dart +++ b/lib/core/extension/ssh_client.dart @@ -107,7 +107,7 @@ extension SSHClientX on SSHClient { bool stdout = true, bool stderr = true, Map? environment, - Future Function(SSHSession)? action, + Future Function(SSHSession)? action, }) async { final session = await execute( command, diff --git a/lib/core/utils/comparator.dart b/lib/core/utils/comparator.dart index 6416683b..604cbf9d 100644 --- a/lib/core/utils/comparator.dart +++ b/lib/core/utils/comparator.dart @@ -80,4 +80,4 @@ Comparator.comparing(Type1::getType2) .thenCompare(Type1::getType4) .thenCompareReversed(Type1::getType5) - */ \ No newline at end of file + */ diff --git a/lib/core/utils/platform/base.dart b/lib/core/utils/platform/base.dart index 44cf9fd2..5a7ce55f 100644 --- a/lib/core/utils/platform/base.dart +++ b/lib/core/utils/platform/base.dart @@ -61,4 +61,4 @@ final isWeb = OS.type == OS.web; final isMobile = OS.type == OS.ios || OS.type == OS.android; final isDesktop = OS.type == OS.linux || OS.type == OS.macos || OS.type == OS.windows; -const isDebuggingMobileLayoutOnDesktop = kDebugMode; \ No newline at end of file +const isDebuggingMobileLayoutOnDesktop = kDebugMode; diff --git a/lib/data/model/server/snippet.dart b/lib/data/model/server/snippet.dart index 4673d9f6..cd7dbae2 100644 --- a/lib/data/model/server/snippet.dart +++ b/lib/data/model/server/snippet.dart @@ -16,18 +16,24 @@ class Snippet implements TagPickable { @HiveField(3) final String? note; + /// List of server id that this snippet should be auto run on + @HiveField(4) + final List? autoRunOn; + const Snippet({ required this.name, required this.script, this.tags, this.note, + this.autoRunOn, }); Snippet.fromJson(Map json) : name = json['name'].toString(), script = json['script'].toString(), tags = json['tags']?.cast(), - note = json['note']?.toString(); + note = json['note']?.toString(), + autoRunOn = json['autoRunOn']?.cast(); Map toJson() { final data = {}; @@ -35,6 +41,7 @@ class Snippet implements TagPickable { data['script'] = script; data['tags'] = tags; data['note'] = note; + data['autoRunOn'] = autoRunOn; return data; } diff --git a/lib/data/model/server/snippet.g.dart b/lib/data/model/server/snippet.g.dart index 91c2944a..5f03d1ae 100644 --- a/lib/data/model/server/snippet.g.dart +++ b/lib/data/model/server/snippet.g.dart @@ -21,13 +21,14 @@ class SnippetAdapter extends TypeAdapter { script: fields[1] as String, tags: (fields[2] as List?)?.cast(), note: fields[3] as String?, + autoRunOn: (fields[4] as List?)?.cast(), ); } @override void write(BinaryWriter writer, Snippet obj) { writer - ..writeByte(4) + ..writeByte(5) ..writeByte(0) ..write(obj.name) ..writeByte(1) @@ -35,7 +36,9 @@ class SnippetAdapter extends TypeAdapter { ..writeByte(2) ..write(obj.tags) ..writeByte(3) - ..write(obj.note); + ..write(obj.note) + ..writeByte(4) + ..write(obj.autoRunOn); } @override diff --git a/lib/data/provider/server.dart b/lib/data/provider/server.dart index f2e7a0de..773314bf 100644 --- a/lib/data/provider/server.dart +++ b/lib/data/provider/server.dart @@ -273,10 +273,9 @@ class ServerProvider extends ChangeNotifier { ensure(await client.run(ShellFunc.installerMkdirs).string); ensure(await client.runForOutput(ShellFunc.installerShellWriter, - action: (session) async { - session.stdin.add(ShellFunc.allScript.uint8List); - }) - .string); + action: (session) async { + session.stdin.add(ShellFunc.allScript.uint8List); + }).string); ensure(await client.run(ShellFunc.installerPermissionModifier).string); } diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 93776c6b..e385738c 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -2,9 +2,9 @@ class BuildData { static const String name = "ServerBox"; - static const int build = 746; - static const String engine = "3.16.9"; - static const String buildAt = "2024-02-15 16:45:05"; - static const int modifications = 2; - static const int script = 37; + static const int build = 761; + static const String engine = "3.19.0"; + static const String buildAt = "2024-02-18 12:48:41"; + static const int modifications = 10; + static const int script = 38; } diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index e54d1ae3..fc918770 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -17,6 +17,7 @@ "autoBackupConflict": "Es kann nur eine automatische Sicherung gleichzeitig aktiviert werden.", "autoCheckUpdate": "Aktualisierung automatisch prüfen", "autoConnect": "Automatisch verbinden", + "autoRun": "Automatischer Start", "autoUpdateHomeWidget": "Home-Widget automatisch aktualisieren", "backup": "Backup", "backupTip": "Das Backup wird nur einfach verschlüsselt.\nBitte bewahre die Datei sicher auf.", @@ -207,8 +208,8 @@ "setting": "Einstellungen", "sftpDlPrepare": "Verbindung vorbereiten...", "sftpRmrDirSummary": "Verwenden Sie \"rm -r\", um das Verzeichnis in SFTP zu löschen.", - "sftpShowFoldersFirst": "Ordner zuerst anzeigen", "sftpSSHConnected": "SFTP Verbunden", + "sftpShowFoldersFirst": "Ordner zuerst anzeigen", "showDistLogo": "Distributionslogo anzeigen", "shutdown": "Abschaltung", "size": "Größe", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index dcfd18de..0d9876d5 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -17,6 +17,7 @@ "autoBackupConflict": "Only one automatic backup can be turned on at the same time.", "autoCheckUpdate": "Auto check update", "autoConnect": "Auto connect", + "autoRun": "Automatic Run", "autoUpdateHomeWidget": "Auto update home widget", "backup": "Backup", "backupTip": "The exported data is simply encrypted. \nPlease keep it safe.", @@ -207,8 +208,8 @@ "setting": "Settings", "sftpDlPrepare": "Preparing to connect...", "sftpRmrDirSummary": "Use `rm -r` to delete a folder in SFTP.", - "sftpShowFoldersFirst": "Disply folders first", "sftpSSHConnected": "SFTP Connected", + "sftpShowFoldersFirst": "Disply folders first", "showDistLogo": "Show distribution logo", "shutdown": "Shutdown", "size": "Size", diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index 9591c9f0..a39010f2 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -17,6 +17,7 @@ "autoBackupConflict": "Une seule sauvegarde automatique peut être activée à la fois.", "autoCheckUpdate": "Vérification automatique des mises à jour", "autoConnect": "Connexion automatique", + "autoRun": "Exécution automatique", "autoUpdateHomeWidget": "Mise à jour automatique du widget d'accueil", "backup": "Sauvegarder", "backupTip": "Les données exportées sont simplement chiffrées. \nVeuillez les conserver en lieu sûr.", @@ -207,8 +208,8 @@ "setting": "Paramètres", "sftpDlPrepare": "Préparation de la connexion...", "sftpRmrDirSummary": "Utilisez `rm -r` pour supprimer un dossier dans SFTP.", - "sftpShowFoldersFirst": "Dossiers d'abord lors du tri", "sftpSSHConnected": "SFTP connecté", + "sftpShowFoldersFirst": "Dossiers d'abord lors du tri", "showDistLogo": "Afficher le logo de la distribution", "shutdown": "Éteindre", "size": "Taille", diff --git a/lib/l10n/app_id.arb b/lib/l10n/app_id.arb index 3b436cb6..41f0c9c4 100644 --- a/lib/l10n/app_id.arb +++ b/lib/l10n/app_id.arb @@ -17,6 +17,7 @@ "autoBackupConflict": "Hanya satu pencadangan otomatis yang dapat diaktifkan pada saat yang bersamaan.", "autoCheckUpdate": "Periksa pembaruan otomatis", "autoConnect": "Hubungkan otomatis", + "autoRun": "Berjalan Otomatis", "autoUpdateHomeWidget": "Widget Rumah Pembaruan Otomatis", "backup": "Cadangan", "backupTip": "Data yang diekspor hanya dienkripsi.\nTolong jaga keamanannya.", @@ -207,8 +208,8 @@ "setting": "Pengaturan", "sftpDlPrepare": "Bersiap untuk terhubung ...", "sftpRmrDirSummary": "Gunakan `rm -r` untuk menghapus dir di SFTP", - "sftpShowFoldersFirst": "Folder ditampilkan lebih dulu", "sftpSSHConnected": "Sftp terhubung", + "sftpShowFoldersFirst": "Folder ditampilkan lebih dulu", "showDistLogo": "Tampilkan logo distribusi", "shutdown": "Matikan", "size": "Ukuran", diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index eae5fddb..d1d5031a 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -17,6 +17,7 @@ "autoBackupConflict": "只能同时开启一个自动备份", "autoCheckUpdate": "自动检查更新", "autoConnect": "自动连接", + "autoRun": "自动运行", "autoUpdateHomeWidget": "自动更新桌面小部件", "backup": "备份", "backupTip": "导出的数据仅进行了简单加密,请妥善保管。", @@ -207,8 +208,8 @@ "setting": "设置", "sftpDlPrepare": "准备连接至服务器...", "sftpRmrDirSummary": "在 SFTP 中使用 `rm -r` 来删除文件夹", - "sftpShowFoldersFirst": "排序时文件夹显示在前", "sftpSSHConnected": "SFTP 已连接...", + "sftpShowFoldersFirst": "排序时文件夹显示在前", "showDistLogo": "显示发行版 Logo", "shutdown": "关机", "size": "大小", diff --git a/lib/l10n/app_zh_tw.arb b/lib/l10n/app_zh_tw.arb index e7dc1200..a0802a35 100644 --- a/lib/l10n/app_zh_tw.arb +++ b/lib/l10n/app_zh_tw.arb @@ -17,6 +17,7 @@ "autoBackupConflict": "只能同時開啓壹個自動備份", "autoCheckUpdate": "自動檢查更新", "autoConnect": "自動連接", + "autoRun": "自動運行", "autoUpdateHomeWidget": "自動更新桌面小部件", "backup": "備份", "backupTip": "導出的數據僅進行了簡單加密,請妥善保管。", @@ -207,8 +208,8 @@ "setting": "設置", "sftpDlPrepare": "準備連接至服務器...", "sftpRmrDirSummary": "在 SFTP 中使用 `rm -r` 來刪除文件夾", - "sftpShowFoldersFirst": "排序時文件夾顯示在前", "sftpSSHConnected": "SFTP 已連接...", + "sftpShowFoldersFirst": "排序時文件夾顯示在前", "showDistLogo": "顯示發行版 Logo", "shutdown": "关机", "size": "大小", diff --git a/lib/view/page/setting/entry.dart b/lib/view/page/setting/entry.dart index f622d262..fa426c45 100644 --- a/lib/view/page/setting/entry.dart +++ b/lib/view/page/setting/entry.dart @@ -855,7 +855,7 @@ class _SettingPageState extends State { children: [ _buildSftpRmrDir(), _buildSftpOpenLastPath(), - _buildSftpShowFoldersFirst(), + _buildSftpShowFoldersFirst(), ].map((e) => CardX(child: e)).toList(), ); } @@ -870,7 +870,7 @@ class _SettingPageState extends State { Widget _buildSftpShowFoldersFirst() { return ListTile( - title: Text(l10n.sftpShowFoldersFirst), + title: Text(l10n.sftpShowFoldersFirst), trailing: StoreSwitch(prop: _setting.sftpShowFoldersFirst), ); } diff --git a/lib/view/page/snippet/edit.dart b/lib/view/page/snippet/edit.dart index 1e9964cd..270de35d 100644 --- a/lib/view/page/snippet/edit.dart +++ b/lib/view/page/snippet/edit.dart @@ -30,8 +30,8 @@ class _SnippetEditPageState extends State final _scriptController = TextEditingController(); final _noteController = TextEditingController(); final _scriptNode = FocusNode(); - - List _tags = []; + final _autoRunOn = ValueNotifier([]); + final _tags = ValueNotifier([]); @override void dispose() { @@ -98,8 +98,9 @@ class _SnippetEditPageState extends State final snippet = Snippet( name: name, script: script, - tags: _tags.isEmpty ? null : _tags, + tags: _tags.value.isEmpty ? null : _tags.value, note: note.isEmpty ? null : note, + autoRunOn: _autoRunOn.value.isEmpty ? null : _autoRunOn.value, ); if (widget.snippet != null) { Pros.snippet.update(widget.snippet!, snippet); @@ -131,15 +132,20 @@ class _SnippetEditPageState extends State label: l10n.note, icon: Icons.note, ), - TagEditor( - tags: _tags, - onChanged: (p0) => setState(() { - _tags = p0; - }), - allTags: [...Pros.snippet.tags], - onRenameTag: (old, n) => setState(() { - Pros.snippet.renameTag(old, n); - }), + ValueListenableBuilder( + valueListenable: _tags, + builder: (_, vals, __) { + return TagEditor( + tags: _tags.value, + onChanged: (p0) => setState(() { + _tags.value = p0; + }), + allTags: [...Pros.snippet.tags], + onRenameTag: (old, n) => setState(() { + Pros.snippet.renameTag(old, n); + }), + ); + }, ), Input( controller: _scriptController, @@ -150,11 +156,41 @@ class _SnippetEditPageState extends State label: l10n.snippet, icon: Icons.code, ), + _buildAutoRunOn(), _buildTip(), ], ); } + Widget _buildAutoRunOn() { + return CardX( + child: ValueListenableBuilder( + valueListenable: _autoRunOn, + builder: (_, vals, __) { + return ListTile( + title: Text(l10n.autoRun), + trailing: const Icon(Icons.keyboard_arrow_right), + subtitle: vals.isEmpty + ? null + : Text( + vals.join(', '), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + onTap: () async { + final serverIds = await context.showPickDialog( + items: Pros.server.serverOrder, + initial: vals, + ); + if (serverIds != null) { + _autoRunOn.value = serverIds; + } + }, + ); + }, + )); + } + Widget _buildTip() { return CardX( child: MarkdownBody( @@ -174,16 +210,20 @@ ${Snippet.fmtArgs.keys.map((e) => '`$e`').join(', ')} @override void afterFirstLayout(BuildContext context) { - if (widget.snippet != null) { - _nameController.text = widget.snippet!.name; - _scriptController.text = widget.snippet!.script; - if (widget.snippet!.note != null) { - _noteController.text = widget.snippet!.note!; + final snippet = widget.snippet; + if (snippet != null) { + _nameController.text = snippet.name; + _scriptController.text = snippet.script; + if (snippet.note != null) { + _noteController.text = snippet.note!; } - if (widget.snippet!.tags != null) { - _tags = widget.snippet!.tags!; - setState(() {}); + if (snippet.tags != null) { + _tags.value = snippet.tags!; + } + + if (snippet.autoRunOn != null) { + _autoRunOn.value = snippet.autoRunOn!; } } } diff --git a/lib/view/page/ssh/page.dart b/lib/view/page/ssh/page.dart index 100702e3..73480720 100644 --- a/lib/view/page/ssh/page.dart +++ b/lib/view/page/ssh/page.dart @@ -382,6 +382,13 @@ class _SSHPageState extends State with AutomaticKeepAliveClientMixin { if (widget.initCmd != null) { _terminal.textInput(widget.initCmd!); _terminal.keyInput(TerminalKey.enter); + } else { + for (final snippet in Pros.snippet.snippets) { + if (snippet.autoRunOn?.contains(widget.spi.id) == true) { + _terminal.textInput(snippet.script); + _terminal.keyInput(TerminalKey.enter); + } + } } await session.done; diff --git a/lib/view/widget/tag.dart b/lib/view/widget/tag.dart index 220cb782..aac5a400 100644 --- a/lib/view/widget/tag.dart +++ b/lib/view/widget/tag.dart @@ -59,7 +59,8 @@ class _TagEditorState extends State { Widget build(BuildContext context) { return CardX( child: ListTile( - leading: const Icon(Icons.tag), + // Align the place of TextField.prefixIcon + leading: const Icon(Icons.tag).padding(const EdgeInsets.only(left: 6)), title: _buildTags(widget.tags), trailing: const Icon(Icons.add).tap( onTap: () { diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 8fdb3da5..adead9c6 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -54,10 +54,10 @@ SPEC CHECKSUMS: dynamic_color: 2eaa27267de1ca20d879fbd6e01259773fb1670f FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 icloud_storage: 33b05299e26d1391d724da8d62860e702380a1cd - path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 + path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38 share_plus: 76dd39142738f7a68dd57b05093b5e8193f220f7 - shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126 + shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695 url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95 window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 9988e07d..c8a93f2b 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -220,7 +220,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 33CC10EC2044A3C60003C045 = { @@ -439,7 +439,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 746; + CURRENT_PROJECT_VERSION = 761; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Server Box"; @@ -449,7 +449,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.746; + MARKETING_VERSION = 1.0.761; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -574,7 +574,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 746; + CURRENT_PROJECT_VERSION = 761; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Server Box"; @@ -584,7 +584,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.746; + MARKETING_VERSION = 1.0.761; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -604,7 +604,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 746; + CURRENT_PROJECT_VERSION = 761; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=macosx*]" = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; @@ -615,7 +615,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.746; + MARKETING_VERSION = 1.0.761; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 24d19f69..20749313 100644 --- a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@