From b96008d6dc8d7ca493b5878133f63de806e3cc43 Mon Sep 17 00:00:00 2001 From: speakeloudest Date: Thu, 22 Jan 2026 18:47:56 -0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E8=B4=A6=E5=8F=B7code=E4=BC=A04=EF=BC=8C=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=B8=B8=E8=A7=81=E9=97=AE=E9=A2=98=E6=96=87=E6=A1=88=EF=BC=8C?= =?UTF-8?q?=E7=A6=81=E7=94=A8=E8=BE=93=E5=85=A5=E6=A1=86=E6=82=AC=E6=B5=AE?= =?UTF-8?q?=E6=8C=89=E9=92=AE=EF=BC=8C=E4=BF=AE=E5=A4=8D=E7=99=BB=E5=BD=95?= =?UTF-8?q?ios=E8=BE=93=E5=85=A5=E6=A1=86=E8=81=9A=E7=84=A6=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/hi_help_controller.dart | 4 +- .../kr_delete_account_controller.dart | 2 +- .../views/kr_delete_account_view.dart | 1 + .../kr_invite/views/kr_invite_view.dart | 1 + .../modules/kr_login/views/kr_login_view.dart | 40 +++++++++---------- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/app/modules/hi_help/controllers/hi_help_controller.dart b/lib/app/modules/hi_help/controllers/hi_help_controller.dart index f5a3380..3688df0 100755 --- a/lib/app/modules/hi_help/controllers/hi_help_controller.dart +++ b/lib/app/modules/hi_help/controllers/hi_help_controller.dart @@ -60,9 +60,9 @@ class HIHelpController extends GetxController { KRMessage( title: '设备与绑定问题', content: [ - '在绑定新设备之前请先添加您的邮箱。', + '在绑定新设备之前请先添加您的邮箱并设置账户密码。', 'Hi快VPN支持最多两台设备同时在线,包括一台iOS设备或Android,加一台Mac或PC。', - '如超出设备数量限制,最早登陆的同类设备将会自动下线,需要重新登陆,设备限制为系统固定设定,不支持调整。', + '如超出设备数量限制,请先手动移除设备后再进行登录,设备限制为系统固定设定,不支持调整。', ], ), KRMessage( diff --git a/lib/app/modules/kr_delete_account/controllers/kr_delete_account_controller.dart b/lib/app/modules/kr_delete_account/controllers/kr_delete_account_controller.dart index 5e9b238..87047c5 100755 --- a/lib/app/modules/kr_delete_account/controllers/kr_delete_account_controller.dart +++ b/lib/app/modules/kr_delete_account/controllers/kr_delete_account_controller.dart @@ -58,7 +58,7 @@ class KRDeleteAccountController extends GetxController { // 发送验证码(简化后的 API 只需要 email 和 type) final result = await _authApi.kr_sendCode( account, // 邮箱地址 - 2, // 删除账号的验证码类型 + 4, // 删除账号的验证码类型 ); result.fold( diff --git a/lib/app/modules/kr_delete_account/views/kr_delete_account_view.dart b/lib/app/modules/kr_delete_account/views/kr_delete_account_view.dart index c4f12ec..3b9772d 100755 --- a/lib/app/modules/kr_delete_account/views/kr_delete_account_view.dart +++ b/lib/app/modules/kr_delete_account/views/kr_delete_account_view.dart @@ -159,6 +159,7 @@ class KRDeleteAccountView extends GetView { height: 50.w, child: TextField( controller: controller.kr_codeController, + contextMenuBuilder: (context, editableTextState) => const SizedBox.shrink(), keyboardType: TextInputType.number, textInputAction: TextInputAction.done, autofillHints: const [AutofillHints.oneTimeCode], diff --git a/lib/app/modules/kr_invite/views/kr_invite_view.dart b/lib/app/modules/kr_invite/views/kr_invite_view.dart index 0dff52d..24ec2f4 100755 --- a/lib/app/modules/kr_invite/views/kr_invite_view.dart +++ b/lib/app/modules/kr_invite/views/kr_invite_view.dart @@ -169,6 +169,7 @@ class KRInviteView extends GetView { RepaintBoundary( child: TextField( controller: controller.otherInviteCodeController, + contextMenuBuilder: (context, editableTextState) => const SizedBox.shrink(), textInputAction: TextInputAction.done, onSubmitted: (_) => controller.kr_handleBindInviteCode(), textAlign: TextAlign.center, diff --git a/lib/app/modules/kr_login/views/kr_login_view.dart b/lib/app/modules/kr_login/views/kr_login_view.dart index bacf572..eb24023 100755 --- a/lib/app/modules/kr_login/views/kr_login_view.dart +++ b/lib/app/modules/kr_login/views/kr_login_view.dart @@ -89,7 +89,7 @@ class KRLoginView extends GetView { final account = KRAppRunData.getInstance().kr_account.value; final isDeviceLogin = account != null && account.startsWith('9000'); - final accountText = (account ==null || isDeviceLogin) + final accountText = (account == null || isDeviceLogin) ? '待绑定' : '${KRAppRunData.getInstance().kr_account.value.toString()}'; @@ -125,7 +125,7 @@ class KRLoginView extends GetView { child: Column( children: [ Obx(() => _buildStandardInputField( - controller: controller.accountController, + textController: controller.accountController, hintText: '请输入邮箱地址', suffixes: const [ '@gmail.com', @@ -161,7 +161,7 @@ class KRLoginView extends GetView { /// 构建标准输入框 Widget _buildStandardInputField({ - required TextEditingController controller, + required TextEditingController textController, required String hintText, bool isPassword = false, List? suffixes, @@ -173,8 +173,9 @@ class KRLoginView extends GetView { VoidCallback? onEditingComplete, }) { return TextField( - controller: controller, + controller: textController, focusNode: focusNode, + contextMenuBuilder: (context, editableTextState) => const SizedBox.shrink(), onEditingComplete: onEditingComplete, obscureText: isPassword, style: KrAppTextStyle( @@ -217,8 +218,8 @@ class KRLoginView extends GetView { // 使用 RawAutocomplete 实现带提示的输入框 return SizedBox( child: RawAutocomplete( - textEditingController: controller, - focusNode: FocusNode(), + textEditingController: textController, + focusNode: this.controller.kr_accountFocusNode, optionsBuilder: (TextEditingValue textEditingValue) { final inputText = textEditingValue.text; @@ -228,22 +229,17 @@ class KRLoginView extends GetView { // 1. 匹配历史记录 (只要输入内容匹配历史记录的开头,或者输入为空) if (historyEmails != null) { if (inputText.isEmpty) { - // 理论上 RawAutocomplete 默认不显示空输入的 options,除非自定义 fieldViewBuilder 监听 - // 但 RawAutocomplete 的 optionsBuilder 在 text 变化时触发。 - // 若要空内容显示,通常需要 Focus 触发。这里先处理有内容的情况, - // 或者如果 RawAutocomplete 支持空内容(通过 initialValue? 不行,得看 triggerMode) - // 简单处理:如果为空,返回所有历史记录 options.addAll(historyEmails); } else { - options.addAll(historyEmails - .where((email) => email.startsWith(inputText))); + options.addAll( + historyEmails.where((email) => email.startsWith(inputText))); } } // 2. 匹配后缀 (仅当有输入且不含 @ 或含 @ 但未完整时) if (suffixes != null && inputText.isNotEmpty) { if (!inputText.contains('@')) { - options.addAll(suffixes.map((suffix) => '$inputText$suffix')); + options.addAll(suffixes.map((suffix) => '$inputText$suffix')); } else { final atIndex = inputText.indexOf('@'); final prefix = inputText.substring(0, atIndex); @@ -254,21 +250,22 @@ class KRLoginView extends GetView { .map((suffix) => '$prefix$suffix')); } } - + // 去重 return options.toSet().toList(); }, fieldViewBuilder: ( BuildContext context, - TextEditingController textEditingController, + TextEditingController + textEditingController, // This textEditingController is provided by RawAutocomplete FocusNode focusNode, VoidCallback onFieldSubmitted, ) { - // 这里我们使用传入的 controller,而不是 fieldViewBuilder 提供的 textEditingController - // 因为我们需要外部控制 controller。 - // 注意:RawAutocomplete 默认会监听 textEditingController, - // 如果我们传入了自己的 controller 给 RawAutocomplete, - // fieldViewBuilder 的 textEditingController 其实就是我们传入的那个。 + // Here we use the passed in textController, not the textEditingController provided by fieldViewBuilder + // because we need to control the textController externally. + // Note: RawAutocomplete listens to textEditingController by default, + // if we pass our own textController to RawAutocomplete, + // the fieldViewBuilder's textEditingController is actually the one we passed. return buildTextField( focusNode: focusNode, onEditingComplete: onFieldSubmitted, @@ -338,6 +335,7 @@ class KRLoginView extends GetView { height: 50, // 固定高度 child: TextField( controller: controller.codeController, + contextMenuBuilder: (context, editableTextState) => const SizedBox.shrink(), keyboardType: TextInputType.number, textInputAction: TextInputAction.done, autofillHints: const [AutofillHints.oneTimeCode],