diff --git a/.gitignore b/.gitignore index acdbea48..d270852d 100644 --- a/.gitignore +++ b/.gitignore @@ -63,3 +63,4 @@ untranlated.json .vscode/settings.json more_build_data.json +trans.txt diff --git a/README.md b/README.md index 71c5da16..bdd5d4bb 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ Especially thanks to dartss [iOS & macOS](https://apps.apple.com/app/id1586449703) / [Android & Linux & Windows](https://github.com/lollipopkit/flutter_server_box/releases) +All deprecated versions before `v930` can be found in [here](https://cdn.lolli.tech/serverbox/?sort=time&order=desc&layout=grid). + ## 🔖 Feature - `Status chart` (CPU, Sensors, GPU...), `SSH` Term, `SFTP`, `Docker & Pkg & Process`... diff --git a/README_zh.md b/README_zh.md index c57cbb0f..f792ca60 100644 --- a/README_zh.md +++ b/README_zh.md @@ -20,6 +20,8 @@ [iOS & macOS](https://apps.apple.com/app/id1586449703) / [Android & Linux & Windows](https://github.com/lollipopkit/flutter_server_box/releases) +所有 `v930` 之前的版本可以在 [这里](https://cdn.lolli.tech/serverbox/?sort=time&order=desc&layout=grid) 找到。 + ## 🔖 特点 - `状态图表`(CPU、传感器、GPU 等), `SSH` 终端, `SFTP`, `Docker & 包 & 进程` 管理器... diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index fa5dfd5b..2df37a20 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -690,7 +690,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 923; + CURRENT_PROJECT_VERSION = 936; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -700,7 +700,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.923; + MARKETING_VERSION = 1.0.936; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -826,7 +826,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 923; + CURRENT_PROJECT_VERSION = 936; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -836,7 +836,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.923; + MARKETING_VERSION = 1.0.936; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -854,7 +854,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 923; + CURRENT_PROJECT_VERSION = 936; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -864,7 +864,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.923; + MARKETING_VERSION = 1.0.936; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -885,7 +885,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 923; + CURRENT_PROJECT_VERSION = 936; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -898,7 +898,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.923; + MARKETING_VERSION = 1.0.936; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; @@ -924,7 +924,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 923; + CURRENT_PROJECT_VERSION = 936; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -937,7 +937,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.923; + MARKETING_VERSION = 1.0.936; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -960,7 +960,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 923; + CURRENT_PROJECT_VERSION = 936; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -973,7 +973,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.923; + MARKETING_VERSION = 1.0.936; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -996,7 +996,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 923; + CURRENT_PROJECT_VERSION = 936; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -1008,7 +1008,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.923; + MARKETING_VERSION = 1.0.936; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; @@ -1037,7 +1037,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 923; + CURRENT_PROJECT_VERSION = 936; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -1049,7 +1049,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.923; + MARKETING_VERSION = 1.0.936; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; @@ -1075,7 +1075,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 923; + CURRENT_PROJECT_VERSION = 936; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -1087,7 +1087,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.923; + MARKETING_VERSION = 1.0.936; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; diff --git a/lib/data/model/container/ps.dart b/lib/data/model/container/ps.dart index f7b4a678..30d639dd 100644 --- a/lib/data/model/container/ps.dart +++ b/lib/data/model/container/ps.dart @@ -3,8 +3,9 @@ import 'dart:convert'; import 'package:fl_lib/fl_lib.dart'; import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/data/model/container/type.dart'; +import 'package:toolbox/data/res/misc.dart'; -abstract final class ContainerPs { +sealed class ContainerPs { final String? id = null; final String? image = null; String? get name; @@ -140,7 +141,11 @@ final class DockerPs implements ContainerPs { String? get cmd => null; @override - bool get running => state?.contains('Up ') ?? false; + bool get running { + if (state?.contains('Exited') == true) return false; + if (state?.contains('Up') == true) return true; + return true; + } @override void parseStats(String s) { @@ -154,12 +159,12 @@ final class DockerPs implements ContainerPs { /// CONTAINER ID NAMES IMAGE STATUS /// a049d689e7a1 aria2-pro p3terx/aria2-pro Up 3 weeks factory DockerPs.parse(String raw) { - final parts = raw.split(RegExp(r'\s{2,}')); + final parts = raw.split(Miscs.multiBlankreg); return DockerPs( id: parts[0], names: parts[1], image: parts[2], - state: parts[3], + state: parts[3].trim(), ); } } diff --git a/lib/data/provider/container.dart b/lib/data/provider/container.dart index 71da1a84..2371906c 100644 --- a/lib/data/provider/container.dart +++ b/lib/data/provider/container.dart @@ -277,8 +277,8 @@ enum ContainerCmdType { ContainerCmdType.version => '$prefix version $_jsonFmt', ContainerCmdType.ps => switch (type) { /// Use [_jsonFmt] in Docker will cause the operation to slow down. - ContainerType.docker => '$prefix ps -a --format "table ' - '{{printf \\"${"%-30.30s " * 4}\\" .ID .Names .Image .Status}}"', + ContainerType.docker => '$prefix ps -a --format "table {{printf \\"' + '%-15.15s ${"%-30.30s " * 3}\\" .ID .Names .Image .Status}}"', ContainerType.podman => '$prefix ps -a $_jsonFmt', }, ContainerCmdType.stats => diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 4ecd0d9d..5e8a176c 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 = 923; + static const int build = 936; static const String engine = "3.22.1"; - static const String buildAt = "2024-06-01 22:31:14"; - static const int modifications = 4; + static const String buildAt = "2024-06-06 16:18:25"; + static const int modifications = 2; static const int script = 48; } diff --git a/lib/data/res/misc.dart b/lib/data/res/misc.dart index efccc276..237ad276 100644 --- a/lib/data/res/misc.dart +++ b/lib/data/res/misc.dart @@ -2,6 +2,7 @@ import 'dart:convert'; abstract final class Miscs { static final blankReg = RegExp(r'\s+'); + static final multiBlankreg = RegExp(r'\s{2,}'); /// RegExp for password request static final pwdRequestWithUserReg = RegExp(r'\[sudo\] password for (.+):'); diff --git a/lib/data/res/url.dart b/lib/data/res/url.dart index 1fedd48e..c0174f49 100644 --- a/lib/data/res/url.dart +++ b/lib/data/res/url.dart @@ -1,6 +1,6 @@ abstract final class Urls { static const cdnBase = 'https://cdn.lolli.tech/serverbox'; - static const updateCfg = '$cdnBase/update.json'; + static const updateCfg = '$cdnBase/update2.json'; static const myGithub = 'https://github.com/lollipopkit'; static const appHelp = '$myGithub/flutter_server_box#-help'; static const appWiki = '$myGithub/flutter_server_box/wiki'; diff --git a/lib/data/store/setting.dart b/lib/data/store/setting.dart index 8f96547d..ae3a9318 100644 --- a/lib/data/store/setting.dart +++ b/lib/data/store/setting.dart @@ -276,6 +276,8 @@ class SettingStore extends PersistentStore { /// fmt: https://example.com/{DIST}-{BRIGHT}.png late final serverLogoUrl = property('serverLogoUrl', ''); + late final betaTest = property('betaTest', false); + // Never show these settings for users // // ------BEGIN------ diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index cd1a0175..f5c6d372 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -2,6 +2,7 @@ "@@locale": "de", "about": "Über", "aboutThanks": "Vielen Dank an die folgenden Personen, die daran teilgenommen haben.\n", + "acceptBeta": "Akzeptieren Sie Testversion-Updates", "add": "Neu", "addAServer": "Server hinzufügen", "addPrivateKey": "Private key hinzufügen", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 86f52dfd..b0141809 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -2,6 +2,7 @@ "@@locale": "en", "about": "About", "aboutThanks": "Thanks to the following people who participated in.", + "acceptBeta": "Accept test version updates", "add": "Add", "addAServer": "add a server", "addPrivateKey": "Add private key", diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 762a1982..60a655dd 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -2,6 +2,7 @@ "@@locale": "es", "about": "Acerca de", "aboutThanks": "Gracias a los siguientes participantes.", + "acceptBeta": "Aceptar actualizaciones de la versión de prueba", "add": "Añadir", "addAServer": "Agregar un servidor", "addPrivateKey": "Agregar una llave privada", diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index c291010f..36260378 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -2,6 +2,7 @@ "@@locale": "fr", "about": "À propos", "aboutThanks": "Merci aux personnes suivantes qui ont participé.", + "acceptBeta": "Accepter les mises à jour de la version de test", "add": "Ajouter", "addAServer": "Ajouter un serveur", "addPrivateKey": "Ajouter une clé privée", diff --git a/lib/l10n/app_id.arb b/lib/l10n/app_id.arb index e6e18431..ab3e68c2 100644 --- a/lib/l10n/app_id.arb +++ b/lib/l10n/app_id.arb @@ -2,6 +2,7 @@ "@@locale": "id", "about": "Tentang", "aboutThanks": "Terima kasih kepada orang -orang berikut yang berpartisipasi.", + "acceptBeta": "Terima pembaruan versi uji coba", "add": "Menambahkan", "addAServer": "tambahkan server", "addPrivateKey": "Tambahkan kunci pribadi", diff --git a/lib/l10n/app_ja.arb b/lib/l10n/app_ja.arb index 95768a67..1ae7ee15 100644 --- a/lib/l10n/app_ja.arb +++ b/lib/l10n/app_ja.arb @@ -2,6 +2,7 @@ "@@locale": "ja", "about": "約", "aboutThanks": "以下の参加者に感謝します。", + "acceptBeta": "テストバージョンの更新を受け入れる", "add": "追加", "addAServer": "サーバーを追加する", "addPrivateKey": "プライベートキーを追加", diff --git a/lib/l10n/app_nl.arb b/lib/l10n/app_nl.arb index aa225aa2..c954a084 100644 --- a/lib/l10n/app_nl.arb +++ b/lib/l10n/app_nl.arb @@ -2,6 +2,7 @@ "@@locale": "nl", "about": "Over", "aboutThanks": "Met dank aan de volgende mensen die hebben deelgenomen aan.", + "acceptBeta": "Accepteer testversie-updates", "add": "Toevoegen", "addAServer": "een server toevoegen", "addPrivateKey": "Privésleutel toevoegen", diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb index 24d1ed37..692965ee 100644 --- a/lib/l10n/app_pt.arb +++ b/lib/l10n/app_pt.arb @@ -2,6 +2,7 @@ "@@locale": "pt", "about": "Sobre", "aboutThanks": "Agradecimentos a todos os participantes.", + "acceptBeta": "Aceitar atualizações da versão de teste", "add": "Adicionar", "addAServer": "Adicionar um servidor", "addPrivateKey": "Adicionar uma chave privada", diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index cd4eab81..9d75ff91 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -2,6 +2,7 @@ "@@locale": "ru", "about": "о", "aboutThanks": "Благодарности всем участникам.", + "acceptBeta": "Принять обновления тестовой версии", "add": "добавить", "addAServer": "добавить сервер", "addPrivateKey": "добавить приватный ключ", diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 3573ce83..143a2715 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -2,6 +2,7 @@ "@@locale": "zh", "about": "关于", "aboutThanks": "感谢以下参与的各位。", + "acceptBeta": "接受测试版更新推送", "add": "新增", "addAServer": "添加服务器", "addPrivateKey": "添加一个私钥", diff --git a/lib/l10n/app_zh_tw.arb b/lib/l10n/app_zh_tw.arb index fdc2e75a..722981cb 100644 --- a/lib/l10n/app_zh_tw.arb +++ b/lib/l10n/app_zh_tw.arb @@ -2,6 +2,7 @@ "@@locale": "zh_TW", "about": "關於", "aboutThanks": "感謝以下參與的各位。", + "acceptBeta": "接受測試版更新推送", "add": "新增", "addAServer": "新增服務器", "addPrivateKey": "新增一個私鑰", diff --git a/lib/main.dart b/lib/main.dart index 4c2b2507..b2a6a648 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -20,6 +20,7 @@ import 'package:toolbox/data/model/server/custom.dart'; import 'package:toolbox/data/model/server/private_key_info.dart'; import 'package:toolbox/data/model/server/server_private_info.dart'; import 'package:toolbox/data/model/server/snippet.dart'; +import 'package:toolbox/data/model/server/wol_cfg.dart'; import 'package:toolbox/data/model/ssh/virtual_key.dart'; import 'package:toolbox/data/res/build_data.dart'; import 'package:toolbox/data/res/misc.dart'; @@ -87,6 +88,7 @@ Future _initData() async { Hive.registerAdapter(NetViewTypeAdapter()); // 5 Hive.registerAdapter(ServerFuncBtnAdapter()); // 6 Hive.registerAdapter(ServerCustomAdapter()); // 7 + Hive.registerAdapter(WakeOnLanCfgAdapter()); // 8 await Stores.setting.init(); await Stores.server.init(); @@ -98,6 +100,8 @@ Future _initData() async { Pros.snippet.load(); Pros.key.load(); await Pros.app.init(); + + if (Stores.setting.betaTest.fetch()) AppUpdate.chan = AppUpdateChan.beta; } void _setupDebug() { diff --git a/lib/view/page/container.dart b/lib/view/page/container.dart index a9f2f68f..3bda2a3d 100644 --- a/lib/view/page/container.dart +++ b/lib/view/page/container.dart @@ -206,7 +206,10 @@ class _ContainerPageState extends State { ], ), Text( - '${item.image ?? l10n.unknown} - ${item.running ? l10n.running : l10n.stopped}', + '${item.image ?? l10n.unknown} - ${switch (item) { + final PodmanPs ps => ps.running ? l10n.running : l10n.stopped, + final DockerPs ps => ps.state, + }}', style: UIs.text13Grey, ), _buildPsItemStats(item), @@ -550,7 +553,10 @@ class _ContainerPageState extends State { case ContainerMenu.logs: AppRoutes.ssh( spi: widget.spi, - initCmd: 'docker logs -f --tail 100 ${dItem.id}', + initCmd: '${switch (_container.type) { + ContainerType.podman => 'podman', + ContainerType.docker => 'docker', + }} logs -f --tail 100 ${dItem.id}', ).go(context); break; case ContainerMenu.terminal: diff --git a/lib/view/page/home/home.dart b/lib/view/page/home/home.dart index 0be63ee7..ab4a7d7f 100644 --- a/lib/view/page/home/home.dart +++ b/lib/view/page/home/home.dart @@ -341,7 +341,7 @@ ${GithubIds.participants.map((e) => '[$e](${e.url})').join(' ')} if (Stores.setting.autoCheckAppUpdate.fetch()) { AppUpdateIface.doUpdate( build: BuildData.build, - url: '${Urls.cdnBase}/update.json', + url: Urls.updateCfg, context: context, ); } diff --git a/lib/view/page/home/wear.dart b/lib/view/page/home/wear.dart index d4070ee4..0ce66569 100644 --- a/lib/view/page/home/wear.dart +++ b/lib/view/page/home/wear.dart @@ -94,7 +94,7 @@ final class _WearHomeState extends State with AfterLayoutMixin { if (Stores.setting.autoCheckAppUpdate.fetch()) { AppUpdateIface.doUpdate( build: BuildData.build, - url: '${Urls.cdnBase}/update.json', + url: Urls.updateCfg, context: context, ); } diff --git a/lib/view/page/setting/entry.dart b/lib/view/page/setting/entry.dart index 0ed0b931..f1d3eb60 100644 --- a/lib/view/page/setting/entry.dart +++ b/lib/view/page/setting/entry.dart @@ -1066,6 +1066,7 @@ class _SettingPageState extends State { leading: const Icon(MingCute.more_3_fill), title: Text(l10n.more), children: [ + _buildBeta(), _buildWakeLock(), if (isAndroid || isIOS) _buildCollectUsage(), _buildCollapseUI(), @@ -1195,4 +1196,12 @@ class _SettingPageState extends State { }, ); } + + Widget _buildBeta() { + return ListTile( + title: const Text('Beta Program'), + subtitle: Text(l10n.acceptBeta, style: UIs.textGrey), + trailing: StoreSwitch(prop: _setting.betaTest), + ); + } } diff --git a/lib/view/page/ssh/page.dart b/lib/view/page/ssh/page.dart index c598654f..9eac3e9e 100644 --- a/lib/view/page/ssh/page.dart +++ b/lib/view/page/ssh/page.dart @@ -515,9 +515,9 @@ class _SSHPageState extends State with AutomaticKeepAliveClientMixin { _terminalStyle = TerminalStyle.fromTextStyle(textStyle); } - Future _showHelp() async { + void _showHelp() { if (!Stores.setting.sshTermHelpShown.fetch()) { - await context.showRoundDialog( + context.showRoundDialog( title: l10n.doc, child: Text(l10n.sshTermHelp), actions: [ diff --git a/lib/view/page/storage/sftp.dart b/lib/view/page/storage/sftp.dart index 974d0a49..cbe441eb 100644 --- a/lib/view/page/storage/sftp.dart +++ b/lib/view/page/storage/sftp.dart @@ -472,19 +472,41 @@ class _SftpPageState extends State with AfterLayoutMixin { void _delete(SftpName file) { context.pop(); final isDir = file.attr.isDirectory; - final useRmr = Stores.setting.sftpRmrDir.fetch(); + var useRmr = Stores.setting.sftpRmrDir.fetch(); final text = () { if (isDir && !useRmr) { - return l10n.askContinue( - '${l10n.dirEmpty}\n${l10n.delete} ' - '${file.filename}', - ); + return l10n.askContinue('${l10n.delete} ${file.filename}'); } return l10n.askContinue('${l10n.delete} ${file.filename}'); }(); + + // Most users don't know that SFTP can't delete a directory which is not + // empty, so we provide a checkbox to let user choose to use `rm -r` or not context.showRoundDialog( - child: Text(text), title: l10n.attention, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ListTile( + title: Text(text), + ), + if (!useRmr) + StatefulBuilder( + builder: (_, setState) { + return CheckboxListTile( + title: Text(l10n.sftpRmrDirSummary), + value: useRmr, + onChanged: (val) { + setState(() { + useRmr = val ?? false; + }); + }, + ); + }, + ), + ], + ), actions: [ TextButton( onPressed: () => context.pop(), diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index b01d4c83..12d9d675 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -471,7 +471,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 923; + CURRENT_PROJECT_VERSION = 936; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Server Box"; @@ -481,7 +481,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.923; + MARKETING_VERSION = 1.0.936; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -608,7 +608,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 923; + CURRENT_PROJECT_VERSION = 936; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Server Box"; @@ -618,7 +618,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.923; + MARKETING_VERSION = 1.0.936; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -638,7 +638,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 923; + CURRENT_PROJECT_VERSION = 936; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=macosx*]" = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; @@ -649,7 +649,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.923; + MARKETING_VERSION = 1.0.936; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/pubspec.lock b/pubspec.lock index 8e0cf09a..743b14b9 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -401,8 +401,8 @@ packages: dependency: "direct main" description: path: "." - ref: "v1.0.31" - resolved-ref: f6322c5c2fad5230d1a882e79d52d1a0d246b8f4 + ref: "v1.0.33" + resolved-ref: "7c4fdde33ec7c9ee226bfe0fd0c148f2d3f3ca54" url: "https://github.com/lppcg/fl_lib" source: git version: "0.0.1" diff --git a/pubspec.yaml b/pubspec.yaml index b62e2fc9..626bcc1d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -53,7 +53,7 @@ dependencies: fl_lib: git: url: https://github.com/lppcg/fl_lib - ref: v1.0.31 + ref: v1.0.33 dependency_overrides: # dartssh2: