fix: 修改样式

This commit is contained in:
speakeloudest 2026-01-22 16:58:54 -08:00
parent 343891b702
commit 73480ce417
22 changed files with 450 additions and 219 deletions

View File

@ -6,7 +6,6 @@
<string>development</string> <string>development</string>
<key>com.apple.developer.associated-domains</key> <key>com.apple.developer.associated-domains</key>
<array> <array>
<string>applinks:alf57p.openinstall.com</string>
<string>applinks:alf57p.oplinking.com</string> <string>applinks:alf57p.oplinking.com</string>
</array> </array>
<key>com.apple.developer.networking.networkextension</key> <key>com.apple.developer.networking.networkextension</key>

View File

@ -6,7 +6,6 @@
<string>development</string> <string>development</string>
<key>com.apple.developer.associated-domains</key> <key>com.apple.developer.associated-domains</key>
<array> <array>
<string>applinks:alf57p.openinstall.com</string>
<string>applinks:alf57p.oplinking.com</string> <string>applinks:alf57p.oplinking.com</string>
</array> </array>
<key>com.apple.developer.networking.networkextension</key> <key>com.apple.developer.networking.networkextension</key>

View File

@ -150,9 +150,9 @@ class KrNodeListItem {
final protocolsList = jsonDecode(protocols) as List; final protocolsList = jsonDecode(protocols) as List;
final currentProtocol = json['protocol']?.toString().toLowerCase() ?? ''; final currentProtocol = json['protocol']?.toString().toLowerCase() ?? '';
KRLogUtil.kr_i('📋 protocols 字段内容 (${protocolsList.length} 个协议):', tag: 'NodeList'); // KRLogUtil.kr_i('📋 protocols 字段内容 (${protocolsList.length} 个协议):', tag: 'NodeList');
for (var i = 0; i < protocolsList.length; i++) { for (var i = 0; i < protocolsList.length; i++) {
KRLogUtil.kr_i(' 协议 $i: ${jsonEncode(protocolsList[i])}', tag: 'NodeList'); // KRLogUtil.kr_i(' 协议 $i: ${jsonEncode(protocolsList[i])}', tag: 'NodeList');
} }
if (protocolsList.isNotEmpty) { if (protocolsList.isNotEmpty) {
@ -170,7 +170,7 @@ class KrNodeListItem {
(currentProtocol == 'shadowsocks' && protocolType == 'ss') || (currentProtocol == 'shadowsocks' && protocolType == 'ss') ||
(currentProtocol == 'ss' && protocolType == 'shadowsocks')) { (currentProtocol == 'ss' && protocolType == 'shadowsocks')) {
matchedProtocolConfig = configMap; matchedProtocolConfig = configMap;
KRLogUtil.kr_i('🎯 找到匹配的协议配置: $protocolType', tag: 'NodeList'); // KRLogUtil.kr_i('🎯 找到匹配的协议配置: $protocolType', tag: 'NodeList');
break; break;
} }
} }
@ -182,22 +182,22 @@ class KrNodeListItem {
// 53441 protocols 287 // 53441 protocols 287
if (port == 0 && targetProtocol['port'] != null) { if (port == 0 && targetProtocol['port'] != null) {
port = _parseIntSafely(targetProtocol['port']); port = _parseIntSafely(targetProtocol['port']);
KRLogUtil.kr_i('✅ 从 protocols 解析端口: $port', tag: 'NodeList'); // KRLogUtil.kr_i('✅ 从 protocols 解析端口: $port', tag: 'NodeList');
} else { } else {
KRLogUtil.kr_i('✅ 保留顶层端口: $port (protocols中的端口: ${targetProtocol['port']})', tag: 'NodeList'); // KRLogUtil.kr_i('✅ 保留顶层端口: $port (protocols中的端口: ${targetProtocol['port']})', tag: 'NodeList');
} }
// cipher // cipher
if (targetProtocol['cipher'] != null && targetProtocol['cipher'].toString().isNotEmpty) { if (targetProtocol['cipher'] != null && targetProtocol['cipher'].toString().isNotEmpty) {
method = targetProtocol['cipher'].toString(); method = targetProtocol['cipher'].toString();
KRLogUtil.kr_i('✅ 从 protocols 解析 cipher: $method', tag: 'NodeList'); // KRLogUtil.kr_i('✅ 从 protocols 解析 cipher: $method', tag: 'NodeList');
} }
} }
} catch (e) { } catch (e) {
KRLogUtil.kr_w('⚠️ 解析 protocols 字段失败: $e', tag: 'NodeList'); KRLogUtil.kr_w('⚠️ 解析 protocols 字段失败: $e', tag: 'NodeList');
} }
} }
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'NodeList'); // KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'NodeList');
return KrNodeListItem( return KrNodeListItem(
id: _parseIntSafely(json['id']), id: _parseIntSafely(json['id']),

View File

@ -132,12 +132,12 @@ class _HINodePageViewState extends State<HINodePageView> {
TextSpan( TextSpan(
children: [ children: [
TextSpan( TextSpan(
text: '${AppTranslations.kr_setting.connectionTypeRule}', text: '智能模式',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14.sp, color: Colors.black), style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14.sp, color: Colors.black),
), ),
TextSpan( TextSpan(
text: AppTranslations.kr_setting.connectionTypeRuleRemark, text: '绕过所在地IP只代理外网服务器速度更快',
style: TextStyle(fontSize: 14.sp, color: Colors.black54), style: TextStyle(fontSize: 14.sp,),
), ),
], ],
), ),
@ -147,12 +147,12 @@ class _HINodePageViewState extends State<HINodePageView> {
TextSpan( TextSpan(
children: [ children: [
TextSpan( TextSpan(
text: '${AppTranslations.kr_setting.connectionTypeGlobal}', text: '全局模式',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14.sp, color: Colors.black), style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14.sp),
), ),
TextSpan( TextSpan(
text: AppTranslations.kr_setting.connectionTypeGlobalRemark, text: '代理所有网络服务器,保障隐私',
style: TextStyle(fontSize: 14.sp, color: Colors.black54), style: TextStyle(fontSize: 14.sp),
), ),
], ],
), ),

View File

@ -16,6 +16,7 @@ import 'dart:convert';
import 'package:kaer_with_panels/utils/snackbar_util.dart'; import 'package:kaer_with_panels/utils/snackbar_util.dart';
import 'package:kaer_with_panels/app/routes/app_pages.dart'; import 'package:kaer_with_panels/app/routes/app_pages.dart';
import 'package:kaer_with_panels/app/common/app_config.dart'; import 'package:kaer_with_panels/app/common/app_config.dart';
import 'package:kaer_with_panels/app/utils/kr_common_util.dart';
class HIUserInfoController extends GetxController { class HIUserInfoController extends GetxController {
/// ///
@ -212,7 +213,8 @@ class HIUserInfoController extends GetxController {
KRLogUtil.kr_e('订阅信息刷新失败: $e', tag: 'DeviceManagement'); KRLogUtil.kr_e('订阅信息刷新失败: $e', tag: 'DeviceManagement');
} }
KRSnackBarUtil.show(AppTranslations.kr_dialog.success, '退出登录成功'); // KRSnackBarUtil.show(AppTranslations.kr_dialog.success, '退出登录成功');
KRCommonUtil.kr_showToast('退出登录成功');
Get.offAllNamed(Routes.KR_HOME); Get.offAllNamed(Routes.KR_HOME);
}, },
); );

View File

@ -273,6 +273,7 @@ class HIUserInfoView extends GetView<HIUserInfoController> {
confirmText: '返回', confirmText: '返回',
// 3. onCancel // 3. onCancel
onCancel: () { onCancel: () {
Get.back();
// //
Get.toNamed(Routes.KR_DELETE_ACCOUNT); Get.toNamed(Routes.KR_DELETE_ACCOUNT);
}, },
@ -547,7 +548,7 @@ class HIUserInfoView extends GetView<HIUserInfoController> {
RichText( RichText(
text: TextSpan( text: TextSpan(
style: TextStyle( style: TextStyle(
fontSize: 10.sp, fontSize: 12.sp,
color: Colors.black, // color: Colors.black, //
), ),
children: <TextSpan>[ children: <TextSpan>[

View File

@ -206,6 +206,7 @@ class KRHomeController extends GetxController with WidgetsBindingObserver {
return; return;
} }
bool isExpired = false; bool isExpired = false;
print('current.expireTime${current.expireTime}');
if (current.expireTime.isNotEmpty) { if (current.expireTime.isNotEmpty) {
try { try {
isExpired = isExpired =

View File

@ -152,7 +152,7 @@ class KRInviteController extends GetxController {
/// ///
Future<void> kr_handleBindInviteCode() async { Future<void> kr_handleBindInviteCode() async {
final text = otherInviteCodeController.text; final text = otherInviteCodeController.text.trim();
if (text.isEmpty) { if (text.isEmpty) {
KRCommonUtil.kr_showToast('请输入邀请码'); KRCommonUtil.kr_showToast('请输入邀请码');
return; return;

View File

@ -172,9 +172,10 @@ class KRInviteView extends GetView<KRInviteController> {
textInputAction: TextInputAction.done, textInputAction: TextInputAction.done,
onSubmitted: (_) => controller.kr_handleBindInviteCode(), onSubmitted: (_) => controller.kr_handleBindInviteCode(),
textAlign: TextAlign.center, textAlign: TextAlign.center,
maxLength: 10,
style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold), style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
decoration: InputDecoration( decoration: InputDecoration(
hintText: '入邀请人邀请码兑换免费时长...', hintText: '码领免费时长...',
hintStyle: const TextStyle(color: Color(0xFFA6A6A6)), hintStyle: const TextStyle(color: Color(0xFFA6A6A6)),
filled: true, filled: true,
fillColor: Colors.transparent, fillColor: Colors.transparent,

View File

@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@ -11,6 +12,7 @@ import 'package:kaer_with_panels/app/localization/app_translations.dart';
import 'package:kaer_with_panels/app/utils/kr_event_bus.dart'; import 'package:kaer_with_panels/app/utils/kr_event_bus.dart';
import 'package:kaer_with_panels/app/services/kr_site_config_service.dart'; import 'package:kaer_with_panels/app/services/kr_site_config_service.dart';
import 'package:kaer_with_panels/app/widgets/dialogs/hi_dialog.dart'; import 'package:kaer_with_panels/app/widgets/dialogs/hi_dialog.dart';
import 'package:kaer_with_panels/app/utils/kr_secure_storage.dart';
import '../../../localization/kr_language_utils.dart'; import '../../../localization/kr_language_utils.dart';
import 'package:kaer_with_panels/app/services/kr_subscribe_service.dart'; import 'package:kaer_with_panels/app/services/kr_subscribe_service.dart';
@ -97,6 +99,9 @@ class KRLoginController extends GetxController
RxList kr_emailList = [].obs; RxList kr_emailList = [].obs;
RxBool kr_isDropdownVisible = false.obs; RxBool kr_isDropdownVisible = false.obs;
///
RxList<String> kr_emailHistory = <String>[].obs;
/// ///
final LayerLink kr_layerLink = LayerLink(); final LayerLink kr_layerLink = LayerLink();
OverlayEntry? overlayEntry; // OverlayEntry? overlayEntry; //
@ -169,14 +174,13 @@ class KRLoginController extends GetxController
} else if (entry == 'bind_email') { } else if (entry == 'bind_email') {
// - // -
kr_loginStatus.value = KRLoginProgressStatus.kr_registerSetPsd; kr_loginStatus.value = KRLoginProgressStatus.kr_registerSetPsd;
}else if (entry == 'login') { } else if (entry == 'login') {
// //
kr_loginStatus.value = KRLoginProgressStatus.kr_loginByPsd; kr_loginStatus.value = KRLoginProgressStatus.kr_loginByPsd;
} }
// entry kr_loginByPsd // entry kr_loginByPsd
} }
// //
_timer = Timer(Duration.zero, () {}); _timer = Timer(Duration.zero, () {});
@ -279,6 +283,20 @@ class KRLoginController extends GetxController
});*/ });*/
kr_initFocus(); kr_initFocus();
//
KRSecureStorage()
.kr_readData(key: KRSecureStorage.EMAIL_HISTORY_KEY)
.then((historyString) {
if (historyString != null && historyString.isNotEmpty) {
try {
final List<dynamic> decodedList = jsonDecode(historyString);
kr_emailHistory.assignAll(decodedList.cast<String>());
} catch (e) {
print('Error decoding email history: $e');
}
}
});
} }
// //
@ -338,8 +356,7 @@ class KRLoginController extends GetxController
}, (r) async { }, (r) async {
HIDialog.show( HIDialog.show(
title: '*重要提示', title: '*重要提示',
message: message: '验证邮件已发送至邮箱,如无法找到,请检查垃圾邮件箱或营销邮件箱。',
'验证邮件已发送至邮箱,如无法找到,请检查垃圾邮件箱或营销邮件箱。',
); );
_startCountdown(); _startCountdown();
@ -353,9 +370,8 @@ class KRLoginController extends GetxController
return; return;
} }
final either = await KRAuthApi().kr_login( final either =
accountController.text, await KRAuthApi().kr_login(accountController.text, psdController.text);
psdController.text);
either.fold((l) { either.fold((l) {
KRCommonUtil.kr_showToast(l.msg); KRCommonUtil.kr_showToast(l.msg);
}, (r) async { }, (r) async {
@ -403,45 +419,49 @@ class KRLoginController extends GetxController
// //
Future<void> performRegister() async { Future<void> performRegister() async {
final either = await KRAuthApi().kr_register( final either = await KRAuthApi().kr_register(
accountController.text, accountController.text,
psdController.text, psdController.text,
code: codeController.text.isEmpty ? null : codeController.text, code: codeController.text.isEmpty ? null : codeController.text,
inviteCode: inviteCodeController.text.isEmpty ? null : inviteCodeController.text, inviteCode: inviteCodeController.text.isEmpty
? null
: inviteCodeController.text,
); );
either.fold( either.fold(
(l) { (l) {
HIDialog.show( HIDialog.show(
message: l.msg, message: l.msg,
preventBackDismiss: true, preventBackDismiss: true,
confirmText: '确定', confirmText: '确定',
); );
return; return;
}, },
(r) async { (r) async {
_saveLoginData(r); _saveLoginData(r);
KRCommonUtil.kr_showToast('登录成功'); KRCommonUtil.kr_showToast('登录成功');
}, },
); );
} }
// //
final subscriptionResult = await KRAuthApi().kr_checkSubscription(accountController.text); final subscriptionResult =
await KRAuthApi().kr_checkSubscription(accountController.text);
subscriptionResult.fold( subscriptionResult.fold(
(error) { (error) {
KRCommonUtil.kr_showToast(error.msg); KRCommonUtil.kr_showToast(error.msg);
}, },
(isFullySubscribed) async { (isFullySubscribed) async {
if (isFullySubscribed) { if (isFullySubscribed) {
HIDialog.show( HIDialog.show(
message: '当前邮箱已有套餐,继续绑定会丢失设备当前套餐,是否继续?', message: '当前邮箱已有套餐,继续绑定会丢失设备当前套餐,是否继续?',
confirmText: '继续', confirmText: '继续',
cancelText: '取消', cancelText: '取消',
onConfirm: performRegister, onConfirm: performRegister,
); );
} else { } else {
await performRegister(); await performRegister();
} }
}, },
); );
} }
@ -479,7 +499,7 @@ class KRLoginController extends GetxController
accountController.text, accountController.text,
codeController.text, codeController.text,
kr_loginStatus.value == KRLoginProgressStatus.kr_registerSendCode kr_loginStatus.value == KRLoginProgressStatus.kr_registerSendCode
? 2 // 2 ? 2 // 2
: 3); // 3 : 3); // 3
either.fold((l) { either.fold((l) {
KRCommonUtil.kr_showToast(l.msg); KRCommonUtil.kr_showToast(l.msg);
@ -508,9 +528,7 @@ class KRLoginController extends GetxController
} }
final either = await KRAuthApi().kr_setNewPsdByForgetPsd( final either = await KRAuthApi().kr_setNewPsdByForgetPsd(
accountController.text, accountController.text, codeController.text, psdController.text);
codeController.text,
psdController.text);
either.fold((l) { either.fold((l) {
KRCommonUtil.kr_showToast(l.msg); KRCommonUtil.kr_showToast(l.msg);
}, (r) async { }, (r) async {
@ -547,15 +565,43 @@ class KRLoginController extends GetxController
/// ///
bool validateEmail(String str) { bool validateEmail(String str) {
return RegExp(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$').hasMatch(str); return RegExp(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$')
.hasMatch(str);
} }
/// ///
void _saveLoginData(String token) { void _saveLoginData(String token) {
KRAppRunData.getInstance().kr_saveUserInfo( KRAppRunData.getInstance().kr_saveUserInfo(
token, token,
accountController.text, accountController.text,
); );
//
KRSecureStorage()
.kr_readData(key: KRSecureStorage.EMAIL_HISTORY_KEY)
.then((historyString) async {
List<String> history = [];
if (historyString != null && historyString.isNotEmpty) {
try {
final List<dynamic> decodedList = jsonDecode(historyString);
history = decodedList.cast<String>();
} catch (e) {
print('Error decoding email history for saving: $e');
}
}
//
if (!history.contains(accountController.text)) {
history.add(accountController.text);
}
// 5
if (history.length > 5) {
history = history.sublist(history.length - 5);
}
await KRSecureStorage().kr_saveData(
key: KRSecureStorage.EMAIL_HISTORY_KEY, value: jsonEncode(history));
});
kr_loginStatus.value = KRLoginProgressStatus.kr_check; kr_loginStatus.value = KRLoginProgressStatus.kr_check;
// / // /

View File

@ -124,10 +124,17 @@ class KRLoginView extends GetView<KRLoginController> {
constraints: BoxConstraints(minHeight: 300.w), constraints: BoxConstraints(minHeight: 300.w),
child: Column( child: Column(
children: [ children: [
_buildStandardInputField( Obx(() => _buildStandardInputField(
controller: controller.accountController, controller: controller.accountController,
hintText: 'Email', hintText: '请输入邮箱地址',
), suffixes: const [
'@gmail.com',
'@outlook.com',
'@qq.com',
'@163.com'
],
historyEmails: controller.kr_emailHistory.toList(),
)),
// SizedBox(height: 10.w), // SizedBox(height: 10.w),
// _buildStandardInputField( // _buildStandardInputField(
// controller: controller.psdController, // controller: controller.psdController,
@ -157,11 +164,18 @@ class KRLoginView extends GetView<KRLoginController> {
required TextEditingController controller, required TextEditingController controller,
required String hintText, required String hintText,
bool isPassword = false, bool isPassword = false,
List<String>? suffixes,
List<String>? historyEmails,
}) { }) {
return SizedBox( //
// height: 50, // Widget buildTextField({
child: TextField( FocusNode? focusNode,
VoidCallback? onEditingComplete,
}) {
return TextField(
controller: controller, controller: controller,
focusNode: focusNode,
onEditingComplete: onEditingComplete,
obscureText: isPassword, obscureText: isPassword,
style: KrAppTextStyle( style: KrAppTextStyle(
fontSize: 16, fontSize: 16,
@ -189,6 +203,122 @@ class KRLoginView extends GetView<KRLoginController> {
borderSide: BorderSide(color: Colors.white, width: 2), borderSide: BorderSide(color: Colors.white, width: 2),
), ),
), ),
);
}
//
if ((suffixes == null || suffixes.isEmpty) &&
(historyEmails == null || historyEmails.isEmpty)) {
return SizedBox(
child: buildTextField(),
);
}
// 使 RawAutocomplete
return SizedBox(
child: RawAutocomplete<String>(
textEditingController: controller,
focusNode: FocusNode(),
optionsBuilder: (TextEditingValue textEditingValue) {
final inputText = textEditingValue.text;
//
List<String> options = [];
// 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)));
}
}
// 2. ( @ @ )
if (suffixes != null && inputText.isNotEmpty) {
if (!inputText.contains('@')) {
options.addAll(suffixes.map((suffix) => '$inputText$suffix'));
} else {
final atIndex = inputText.indexOf('@');
final prefix = inputText.substring(0, atIndex);
final domainInput = inputText.substring(atIndex); // @
options.addAll(suffixes
.where((suffix) => suffix.startsWith(domainInput))
.map((suffix) => '$prefix$suffix'));
}
}
//
return options.toSet().toList();
},
fieldViewBuilder: (
BuildContext context,
TextEditingController textEditingController,
FocusNode focusNode,
VoidCallback onFieldSubmitted,
) {
// 使 controller fieldViewBuilder textEditingController
// controller
// RawAutocomplete textEditingController
// controller RawAutocomplete
// fieldViewBuilder textEditingController
return buildTextField(
focusNode: focusNode,
onEditingComplete: onFieldSubmitted,
);
},
optionsViewBuilder: (
BuildContext context,
AutocompleteOnSelected<String> onSelected,
Iterable<String> options,
) {
return Align(
alignment: Alignment.topLeft,
child: Material(
elevation: 4.0,
color: const Color(0xFF1E1E1E), //
borderRadius: BorderRadius.circular(8.r),
child: Container(
constraints: BoxConstraints(
maxHeight: 200.w,
maxWidth: 300.w, //
),
width: MediaQuery.of(context).size.width - 80.w, // padding
child: ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final String option = options.elementAt(index);
return InkWell(
onTap: () {
onSelected(option);
},
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 16.w, vertical: 12.w),
child: Text(
option,
style: KrAppTextStyle(
fontSize: 14,
color: Colors.white,
),
),
),
);
},
),
),
),
);
},
), ),
); );
} }

View File

@ -247,38 +247,6 @@ class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController>
); );
} }
//
Widget _kr_buildAccountSection(BuildContext context) {
return Container(
margin: EdgeInsets.all(16),
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: BorderRadius.circular(12),
),
child: Row(
children: [
Text(
AppTranslations.kr_purchaseMembership.myAccount,
style: KrAppTextStyle(
fontSize: 14,
color: Theme.of(context).textTheme.bodyMedium?.color,
),
),
const Spacer(),
Obx(() => Text(
controller.kr_userEmail.value,
style: KrAppTextStyle(
fontSize: 14,
color: Theme.of(context).textTheme.bodySmall?.color,
),
)),
],
),
);
}
// //
Widget _kr_buildPlanOptionCard( Widget _kr_buildPlanOptionCard(
KRPackageListItem plan, KRPackageListItem plan,
@ -428,9 +396,7 @@ class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController>
style: TextStyle( style: TextStyle(
color: Colors.black, // color: Colors.black, //
fontSize: 14, fontSize: 14,
fontWeight: index == 1 fontWeight: FontWeight.w600,
? FontWeight.w300
: FontWeight.w600,
), ),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),

View File

@ -259,7 +259,7 @@ class HttpUtil {
/// HTTP /// HTTP
class _KRSimpleHttpInterceptor extends Interceptor { class _KRSimpleHttpInterceptor extends Interceptor {
/// ///
static const bool KR_HTTP_PRINT = true; static const bool KR_HTTP_PRINT = false;
final Dio _dio; final Dio _dio;
_KRSimpleHttpInterceptor(this._dio); _KRSimpleHttpInterceptor(this._dio);
static String? _lastPath; static String? _lastPath;

View File

@ -607,6 +607,15 @@ class KRSingBoxImp {
KRLogUtil.kr_i('✅ [智能代理模式] region 设为 $effectiveRegion', tag: 'SingBox'); KRLogUtil.kr_i('✅ [智能代理模式] region 设为 $effectiveRegion', tag: 'SingBox');
} }
final useWindowsDnsDefaults = Platform.isWindows;
final remoteDnsAddress = useWindowsDnsDefaults
? 'udp://1.1.1.1'
: 'https://dns.google/dns-query';
final directDnsAddress = useWindowsDnsDefaults
? (effectiveRegion == 'cn' ? 'udp://223.5.5.5' : 'udp://1.1.1.1')
: 'local';
final dnsDomainStrategy = useWindowsDnsDefaults ? '' : 'prefer_ipv4';
final op = { final op = {
"region": effectiveRegion, // 🔧 region "region": effectiveRegion, // 🔧 region
"block-ads": false, // hiddify-app: 广 "block-ads": false, // hiddify-app: 广
@ -616,11 +625,10 @@ class KRSingBoxImp {
"resolve-destination": false, "resolve-destination": false,
"ipv6-mode": "ipv6-mode":
"ipv4_only", // hiddify-app: 使 IPv4 (: ipv4_only, prefer_ipv4, prefer_ipv6, ipv6_only) "ipv4_only", // hiddify-app: 使 IPv4 (: ipv4_only, prefer_ipv4, prefer_ipv6, ipv6_only)
"remote-dns-address": "remote-dns-address": remoteDnsAddress, // 使 Google DoH DNS
"https://dns.google/dns-query", // 使 Google DoH DNS "remote-dns-domain-strategy": dnsDomainStrategy,
"remote-dns-domain-strategy": "prefer_ipv4", "direct-dns-address": directDnsAddress, // 使 DNS
"direct-dns-address": "local", // 使 DNS "direct-dns-domain-strategy": dnsDomainStrategy,
"direct-dns-domain-strategy": "prefer_ipv4",
"mixed-port": kr_port, "mixed-port": kr_port,
"tproxy-port": kr_port, "tproxy-port": kr_port,
"local-dns-port": 36450, "local-dns-port": 36450,

View File

@ -22,7 +22,6 @@ class KRCommonUtil {
_kr_isOpeningCustomerService = true; _kr_isOpeningCustomerService = true;
try { try {
kr_showToast('userInfo.openingCustomerService'.tr);
await Get.toNamed(Routes.KR_CHATWOOT); await Get.toNamed(Routes.KR_CHATWOOT);
} catch (e) { } catch (e) {
debugPrint('打开客服失败: $e'); debugPrint('打开客服失败: $e');

View File

@ -17,6 +17,9 @@ class KRSecureStorage {
// //
static const String _boxName = 'kaer_secure_storage'; static const String _boxName = 'kaer_secure_storage';
//
static const String EMAIL_HISTORY_KEY = 'email_history';
// //
static const String _encryptionKey = 'kaer_secure_storage_key'; static const String _encryptionKey = 'kaer_secure_storage_key';

View File

@ -179,7 +179,6 @@ class HIBaseScaffold extends StatelessWidget {
style: TextStyle( style: TextStyle(
color: Colors.black, // 使 color: Colors.black, // 使
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w100,
), ),
), ),
), ),

View File

@ -53,20 +53,21 @@ class FFISingboxService with InfraLogger implements SingboxService {
return p.join("libcore", libName); return p.join("libcore", libName);
} }
// 🔧 使 if (Platform.isMacOS) {
// // app binary
final devPath = p.join("libcore", "bin", libName); final execPath = File(Platform.resolvedExecutable).absolute.path;
if (kDebugMode) {
print('🔍 [FFI] 检查开发环境路径: $devPath');
print('🔍 [FFI] 当前工作目录: ${Directory.current.path}');
print('🔍 [FFI] 文件是否存在: ${File(devPath).existsSync()}');
}
if (File(devPath).existsSync()) { // App binary Contents/MacOS, libcore Contents/Frameworks
if (kDebugMode) { final bundleDir = p.dirname(p.dirname(execPath)); // Contents
print('✅ [FFI] 使用开发环境路径: $devPath'); final frameworksPath = p.join(bundleDir, 'Frameworks', libName);
if (File(frameworksPath).existsSync()) {
if (kDebugMode) print('✅ [FFI] macOS bundle 相对路径: $frameworksPath');
return frameworksPath;
} else {
print('⚠️ [FFI] 未找到 libcore.dylibfallback 到默认路径: $libName');
return libName;
} }
return devPath;
} }
// 使bundle中的路径 // 使bundle中的路径
@ -82,22 +83,28 @@ class FFISingboxService with InfraLogger implements SingboxService {
print('🚀 [FFI] init() 开始'); print('🚀 [FFI] init() 开始');
} }
loggy.debug("initializing"); loggy.debug("initializing");
final box = FFISingboxService._box;
box.setupOnce(NativeApi.initializeApiDLData);
// setupOnce worker isolate _ffiLoadLibrary // setupOnce worker isolate _ffiLoadLibrary
// isolate // isolate
if (kDebugMode) { if (kDebugMode) {
print('⏭️ [FFI] 跳过主 isolate 中的 setupOnce将在 worker isolate 中执行)'); print('⏭️ [FFI] 跳过主 isolate 中的 setupOnce将在 worker isolate 中执行)');
} }
print('📡 [FFI] 主 Isolate setupOnce 执行完毕Port 已创建');
if (kDebugMode) { if (kDebugMode) {
print('📡 [FFI] 创建 ReceivePort'); print('📡 [FFI] 创建 ReceivePort');
} }
_statusReceiver = ReceivePort('service status receiver'); _statusReceiver = ReceivePort('service status receiver');
print('📡 [FFI] Dart port created: ${_statusReceiver.sendPort.nativePort}');
if (kDebugMode) { if (kDebugMode) {
print('🔄 [FFI] 设置状态流'); print('🔄 [FFI] 设置状态流');
} }
final source = _statusReceiver.asBroadcastStream().map((event) => jsonDecode(event as String)).map(SingboxStatus.fromEvent); final source = _statusReceiver
.asBroadcastStream()
.map((event) => jsonDecode(event as String))
.map(SingboxStatus.fromEvent);
_status = ValueConnectableStream.seeded( _status = ValueConnectableStream.seeded(
source, source,
const SingboxStopped(), const SingboxStopped(),
@ -125,7 +132,7 @@ class FFISingboxService with InfraLogger implements SingboxService {
_logger.debug('[黑屏调试] setup() 开始调用 libcore.dll - $startTime'); _logger.debug('[黑屏调试] setup() 开始调用 libcore.dll - $startTime');
final err = await IsolateWorker().execute( final err = await IsolateWorker().execute(
() => _ffiSetup(baseDir, workingDir, tempDir, port, debugFlag), () => _ffiSetup(baseDir, workingDir, tempDir, port, debugFlag),
allowSyncFallback: false, allowSyncFallback: false,
); );
@ -137,9 +144,15 @@ class FFISingboxService with InfraLogger implements SingboxService {
_logger.error('[黑屏调试] setup() 错误: $err'); _logger.error('[黑屏调试] setup() 错误: $err');
return left(err); return left(err);
} }
if (kDebugMode) {
print('✅ [FFI][ORDER] setup() finished OK');
}
return right(unit); return right(unit);
} catch (e) { } catch (e) {
_logger.error('[黑屏调试] setup() 异常: $e'); _logger.error('[黑屏调试] setup() 异常: $e');
if (kDebugMode) {
print('❌ [FFI][ORDER] setup() threw: $e');
}
return left(e.toString()); return left(e.toString());
} }
}); });
@ -147,15 +160,15 @@ class FFISingboxService with InfraLogger implements SingboxService {
@override @override
TaskEither<String, Unit> validateConfigByPath( TaskEither<String, Unit> validateConfigByPath(
String path, String path,
String tempPath, String tempPath,
bool debug, bool debug,
) { ) {
final debugFlag = debug ? 1 : 0; final debugFlag = debug ? 1 : 0;
return TaskEither(() async { return TaskEither(() async {
try { try {
final err = await IsolateWorker().execute( final err = await IsolateWorker().execute(
() => _ffiValidateConfig(path, tempPath, debugFlag), () => _ffiValidateConfig(path, tempPath, debugFlag),
allowSyncFallback: false, allowSyncFallback: false,
); );
if (err != null && err.isNotEmpty) { if (err != null && err.isNotEmpty) {
@ -177,7 +190,7 @@ class FFISingboxService with InfraLogger implements SingboxService {
_logger.debug('[黑屏调试] changeOptions 开始调用 libcore.dll - $startTime'); _logger.debug('[黑屏调试] changeOptions 开始调用 libcore.dll - $startTime');
final err = await IsolateWorker().execute( final err = await IsolateWorker().execute(
() => _ffiChangeOptions(json), () => _ffiChangeOptions(json),
allowSyncFallback: false, allowSyncFallback: false,
); );
@ -199,12 +212,12 @@ class FFISingboxService with InfraLogger implements SingboxService {
@override @override
TaskEither<String, String> generateFullConfigByPath( TaskEither<String, String> generateFullConfigByPath(
String path, String path,
) { ) {
return TaskEither(() async { return TaskEither(() async {
try { try {
final result = await IsolateWorker().execute( final result = await IsolateWorker().execute(
() => _ffiGenerateFullConfig(path), () => _ffiGenerateFullConfig(path),
allowSyncFallback: false, allowSyncFallback: false,
); );
final ok = result.isNotEmpty && result[0] == true; final ok = result.isNotEmpty && result[0] == true;
@ -221,18 +234,21 @@ class FFISingboxService with InfraLogger implements SingboxService {
@override @override
TaskEither<String, Unit> start( TaskEither<String, Unit> start(
String configPath, String configPath,
String name, String name,
bool disableMemoryLimit, bool disableMemoryLimit,
) { ) {
loggy.debug("starting, memory limit: [${!disableMemoryLimit}]"); loggy.debug("starting, memory limit: [${!disableMemoryLimit}]");
if (kDebugMode) {
print('🚦 [FFI][ORDER] start() entered (after setup)');
}
return TaskEither(() async { return TaskEither(() async {
try { try {
final startTime = DateTime.now(); final startTime = DateTime.now();
_logger.debug('[黑屏调试] start() 开始调用 libcore.dll - $startTime'); _logger.debug('[黑屏调试] start() 开始调用 libcore.dll - $startTime');
final err = await IsolateWorker().execute( final err = await IsolateWorker().execute(
() => _ffiStart(configPath, disableMemoryLimit), () => _ffiStart(configPath, disableMemoryLimit),
allowSyncFallback: false, allowSyncFallback: false,
); );
@ -244,9 +260,15 @@ class FFISingboxService with InfraLogger implements SingboxService {
_logger.error('[黑屏调试] start() 错误: $err'); _logger.error('[黑屏调试] start() 错误: $err');
return left(err); return left(err);
} }
if (kDebugMode) {
print('✅ [FFI][ORDER] start() finished OK');
}
return right(unit); return right(unit);
} catch (e) { } catch (e) {
_logger.error('[黑屏调试] start() 异常: $e'); _logger.error('[黑屏调试] start() 异常: $e');
if (kDebugMode) {
print('❌ [FFI][ORDER] start() threw: $e');
}
return left(e.toString()); return left(e.toString());
} }
}); });
@ -282,15 +304,15 @@ class FFISingboxService with InfraLogger implements SingboxService {
@override @override
TaskEither<String, Unit> restart( TaskEither<String, Unit> restart(
String configPath, String configPath,
String name, String name,
bool disableMemoryLimit, bool disableMemoryLimit,
) { ) {
loggy.debug("restarting, memory limit: [${!disableMemoryLimit}]"); loggy.debug("restarting, memory limit: [${!disableMemoryLimit}]");
return TaskEither(() async { return TaskEither(() async {
try { try {
final err = await IsolateWorker().execute( final err = await IsolateWorker().execute(
() => _ffiRestart(configPath, disableMemoryLimit), () => _ffiRestart(configPath, disableMemoryLimit),
allowSyncFallback: false, allowSyncFallback: false,
); );
if (err != null && err.isNotEmpty) { if (err != null && err.isNotEmpty) {
@ -328,7 +350,7 @@ class FFISingboxService with InfraLogger implements SingboxService {
_serviceStatsStream = null; _serviceStatsStream = null;
}, },
).map( ).map(
(event) { (event) {
if (event case String _) { if (event case String _) {
if (event.startsWith('error:')) { if (event.startsWith('error:')) {
loggy.error("[service stats client] error received: $event"); loggy.error("[service stats client] error received: $event");
@ -343,12 +365,18 @@ class FFISingboxService with InfraLogger implements SingboxService {
}, },
); );
final err = _box.startCommandClient(1, receiver.sendPort.nativePort).cast<Utf8>().toDartString(); if (kDebugMode) {
print(
'📡 [FFI][ORDER] watchStats startCommandClient port=${receiver.sendPort.nativePort}');
}
final err = _box
.startCommandClient(1, receiver.sendPort.nativePort)
.cast<Utf8>()
.toDartString();
if (err.isNotEmpty) { if (err.isNotEmpty) {
loggy.error("error starting status command: $err"); loggy.error("error starting status command: $err");
throw err; throw err;
} }
return _serviceStatsStream = statusStream; return _serviceStatsStream = statusStream;
} }
@ -368,7 +396,7 @@ class FFISingboxService with InfraLogger implements SingboxService {
} }
}, },
).map( ).map(
(event) { (event) {
if (event case String _) { if (event case String _) {
if (event.startsWith('error:')) { if (event.startsWith('error:')) {
logger.error("error received: $event"); logger.error("error received: $event");
@ -385,7 +413,14 @@ class FFISingboxService with InfraLogger implements SingboxService {
); );
try { try {
final err = _box.startCommandClient(5, receiver.sendPort.nativePort).cast<Utf8>().toDartString(); if (kDebugMode) {
print(
'📡 [FFI][ORDER] watchGroups startCommandClient port=${receiver.sendPort.nativePort}');
}
final err = _box
.startCommandClient(5, receiver.sendPort.nativePort)
.cast<Utf8>()
.toDartString();
if (err.isNotEmpty) { if (err.isNotEmpty) {
logger.error("error starting group command: $err"); logger.error("error starting group command: $err");
throw err; throw err;
@ -412,7 +447,7 @@ class FFISingboxService with InfraLogger implements SingboxService {
} }
}, },
).map( ).map(
(event) { (event) {
if (event case String _) { if (event case String _) {
if (event.startsWith('error:')) { if (event.startsWith('error:')) {
logger.error(event); logger.error(event);
@ -429,7 +464,14 @@ class FFISingboxService with InfraLogger implements SingboxService {
); );
try { try {
final err = _box.startCommandClient(13, receiver.sendPort.nativePort).cast<Utf8>().toDartString(); if (kDebugMode) {
print(
'📡 [FFI][ORDER] watchActiveGroups startCommandClient port=${receiver.sendPort.nativePort}');
}
final err = _box
.startCommandClient(13, receiver.sendPort.nativePort)
.cast<Utf8>()
.toDartString();
if (err.isNotEmpty) { if (err.isNotEmpty) {
logger.error("error starting: $err"); logger.error("error starting: $err");
throw err; throw err;
@ -447,7 +489,7 @@ class FFISingboxService with InfraLogger implements SingboxService {
return TaskEither(() async { return TaskEither(() async {
try { try {
final err = await IsolateWorker().execute( final err = await IsolateWorker().execute(
() => _ffiSelectOutbound(groupTag, outboundTag), () => _ffiSelectOutbound(groupTag, outboundTag),
allowSyncFallback: false, allowSyncFallback: false,
); );
if (err != null && err.isNotEmpty) { if (err != null && err.isNotEmpty) {
@ -465,7 +507,7 @@ class FFISingboxService with InfraLogger implements SingboxService {
return TaskEither(() async { return TaskEither(() async {
try { try {
final err = await IsolateWorker().execute( final err = await IsolateWorker().execute(
() => _ffiUrlTest(groupTag), () => _ffiUrlTest(groupTag),
allowSyncFallback: false, allowSyncFallback: false,
); );
if (err != null && err.isNotEmpty) { if (err != null && err.isNotEmpty) {
@ -484,7 +526,9 @@ class FFISingboxService with InfraLogger implements SingboxService {
@override @override
Stream<List<String>> watchLogs(String path) async* { Stream<List<String>> watchLogs(String path) async* {
yield await _readLogFile(File(path)); yield await _readLogFile(File(path));
yield* Watcher(path, pollingDelay: const Duration(seconds: 1)).events.asyncMap((event) async { yield* Watcher(path, pollingDelay: const Duration(seconds: 1))
.events
.asyncMap((event) async {
if (event.type == ChangeType.MODIFY) { if (event.type == ChangeType.MODIFY) {
await _readLogFile(File(path)); await _readLogFile(File(path));
} }
@ -502,7 +546,8 @@ class FFISingboxService with InfraLogger implements SingboxService {
Future<List<String>> _readLogFile(File file) async { Future<List<String>> _readLogFile(File file) async {
if (_logFilePosition == 0 && file.lengthSync() == 0) return []; if (_logFilePosition == 0 && file.lengthSync() == 0) return [];
final content = await file.openRead(_logFilePosition).transform(utf8.decoder).join(); final content =
await file.openRead(_logFilePosition).transform(utf8.decoder).join();
_logFilePosition = file.lengthSync(); _logFilePosition = file.lengthSync();
final lines = const LineSplitter().convert(content); final lines = const LineSplitter().convert(content);
if (lines.length > 300) { if (lines.length > 300) {
@ -527,7 +572,8 @@ class FFISingboxService with InfraLogger implements SingboxService {
return TaskEither(() async { return TaskEither(() async {
try { try {
final result = await IsolateWorker().execute( final result = await IsolateWorker().execute(
() => _ffiGenerateWarpConfig(licenseKey, previousAccountId, previousAccessToken), () => _ffiGenerateWarpConfig(
licenseKey, previousAccountId, previousAccessToken),
allowSyncFallback: false, allowSyncFallback: false,
); );
final ok = result.isNotEmpty && result[0] == true; final ok = result.isNotEmpty && result[0] == true;
@ -552,38 +598,45 @@ SingboxNativeLibrary _ffiLoadLibrary() {
} }
String? _ffiSetup( String? _ffiSetup(
String baseDir, String baseDir,
String workingDir, String workingDir,
String tempDir, String tempDir,
int statusPort, int statusPort,
int debugFlag, int debugFlag,
) { ) {
if (kDebugMode) {
print(
'🧭 [FFI][ORDER] _ffiSetup inputs statusPort=$statusPort base="$baseDir" working="$workingDir" temp="$tempDir" debug="$debugFlag"');
}
final box = _ffiLoadLibrary(); final box = _ffiLoadLibrary();
final err = box final err = box
.setup( .setup(
baseDir.toNativeUtf8().cast(), baseDir.toNativeUtf8().cast(),
workingDir.toNativeUtf8().cast(), workingDir.toNativeUtf8().cast(),
tempDir.toNativeUtf8().cast(), tempDir.toNativeUtf8().cast(),
statusPort, statusPort,
debugFlag, debugFlag,
) )
.cast<Utf8>() .cast<Utf8>()
.toDartString(); .toDartString();
if (kDebugMode) {
print('🧭 [FFI][ORDER] _ffiSetup returned err="${err.isEmpty ? '' : err}"');
}
return err.isEmpty ? null : err; return err.isEmpty ? null : err;
} }
String? _ffiValidateConfig( String? _ffiValidateConfig(
String path, String path,
String tempPath, String tempPath,
int debugFlag, int debugFlag,
) { ) {
final box = _ffiLoadLibrary(); final box = _ffiLoadLibrary();
final err = box final err = box
.parse( .parse(
path.toNativeUtf8().cast(), path.toNativeUtf8().cast(),
tempPath.toNativeUtf8().cast(), tempPath.toNativeUtf8().cast(),
debugFlag, debugFlag,
) )
.cast<Utf8>() .cast<Utf8>()
.toDartString(); .toDartString();
return err.isEmpty ? null : err; return err.isEmpty ? null : err;
@ -591,7 +644,10 @@ String? _ffiValidateConfig(
String? _ffiChangeOptions(String optionsJson) { String? _ffiChangeOptions(String optionsJson) {
final box = _ffiLoadLibrary(); final box = _ffiLoadLibrary();
final err = box.changeHiddifyOptions(optionsJson.toNativeUtf8().cast()).cast<Utf8>().toDartString(); final err = box
.changeHiddifyOptions(optionsJson.toNativeUtf8().cast())
.cast<Utf8>()
.toDartString();
return err.isEmpty ? null : err; return err.isEmpty ? null : err;
} }
@ -599,8 +655,8 @@ List<Object?> _ffiGenerateFullConfig(String path) {
final box = _ffiLoadLibrary(); final box = _ffiLoadLibrary();
final response = box final response = box
.generateConfig( .generateConfig(
path.toNativeUtf8().cast(), path.toNativeUtf8().cast(),
) )
.cast<Utf8>() .cast<Utf8>()
.toDartString(); .toDartString();
if (response.startsWith("error")) { if (response.startsWith("error")) {
@ -613,9 +669,9 @@ String? _ffiStart(String configPath, bool disableMemoryLimit) {
final box = _ffiLoadLibrary(); final box = _ffiLoadLibrary();
final err = box final err = box
.start( .start(
configPath.toNativeUtf8().cast(), configPath.toNativeUtf8().cast(),
disableMemoryLimit ? 1 : 0, disableMemoryLimit ? 1 : 0,
) )
.cast<Utf8>() .cast<Utf8>()
.toDartString(); .toDartString();
return err.isEmpty ? null : err; return err.isEmpty ? null : err;
@ -631,9 +687,9 @@ String? _ffiRestart(String configPath, bool disableMemoryLimit) {
final box = _ffiLoadLibrary(); final box = _ffiLoadLibrary();
final err = box final err = box
.restart( .restart(
configPath.toNativeUtf8().cast(), configPath.toNativeUtf8().cast(),
disableMemoryLimit ? 1 : 0, disableMemoryLimit ? 1 : 0,
) )
.cast<Utf8>() .cast<Utf8>()
.toDartString(); .toDartString();
return err.isEmpty ? null : err; return err.isEmpty ? null : err;
@ -643,9 +699,9 @@ String? _ffiSelectOutbound(String groupTag, String outboundTag) {
final box = _ffiLoadLibrary(); final box = _ffiLoadLibrary();
final err = box final err = box
.selectOutbound( .selectOutbound(
groupTag.toNativeUtf8().cast(), groupTag.toNativeUtf8().cast(),
outboundTag.toNativeUtf8().cast(), outboundTag.toNativeUtf8().cast(),
) )
.cast<Utf8>() .cast<Utf8>()
.toDartString(); .toDartString();
return err.isEmpty ? null : err; return err.isEmpty ? null : err;
@ -653,22 +709,23 @@ String? _ffiSelectOutbound(String groupTag, String outboundTag) {
String? _ffiUrlTest(String groupTag) { String? _ffiUrlTest(String groupTag) {
final box = _ffiLoadLibrary(); final box = _ffiLoadLibrary();
final err = box.urlTest(groupTag.toNativeUtf8().cast()).cast<Utf8>().toDartString(); final err =
box.urlTest(groupTag.toNativeUtf8().cast()).cast<Utf8>().toDartString();
return err.isEmpty ? null : err; return err.isEmpty ? null : err;
} }
List<Object?> _ffiGenerateWarpConfig( List<Object?> _ffiGenerateWarpConfig(
String licenseKey, String licenseKey,
String previousAccountId, String previousAccountId,
String previousAccessToken, String previousAccessToken,
) { ) {
final box = _ffiLoadLibrary(); final box = _ffiLoadLibrary();
final response = box final response = box
.generateWarpConfig( .generateWarpConfig(
licenseKey.toNativeUtf8().cast(), licenseKey.toNativeUtf8().cast(),
previousAccountId.toNativeUtf8().cast(), previousAccountId.toNativeUtf8().cast(),
previousAccessToken.toNativeUtf8().cast(), previousAccessToken.toNativeUtf8().cast(),
) )
.cast<Utf8>() .cast<Utf8>()
.toDartString(); .toDartString();
if (response.startsWith("error:")) { if (response.startsWith("error:")) {

View File

@ -564,6 +564,12 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
/usr/lib/swift,
"'@executable_path/../Frameworks'",
"\"${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}\"",
);
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx; SDKROOT = macosx;
@ -581,10 +587,11 @@
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = NJRRF427XB; DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=macosx*]" = NJRRF427XB;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = HiFastVPN; INFOPLIST_KEY_CFBundleDisplayName = HiFastVPN;
@ -595,6 +602,7 @@
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_BUNDLE_IDENTIFIER = com.taw.hifastvpn.mac; PRODUCT_BUNDLE_IDENTIFIER = com.taw.hifastvpn.mac;
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "HiFastVPN-Mac-Pord";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
}; };
name = Profile; name = Profile;
@ -654,6 +662,12 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
/usr/lib/swift,
"'@executable_path/../Frameworks'",
"\"${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}\"",
);
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
@ -703,6 +717,12 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
/usr/lib/swift,
"'@executable_path/../Frameworks'",
"\"${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}\"",
);
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx; SDKROOT = macosx;
@ -720,10 +740,11 @@
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = NJRRF427XB; DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=macosx*]" = NJRRF427XB;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = HiFastVPN; INFOPLIST_KEY_CFBundleDisplayName = HiFastVPN;
@ -734,6 +755,7 @@
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_BUNDLE_IDENTIFIER = com.taw.hifastvpn.mac; PRODUCT_BUNDLE_IDENTIFIER = com.taw.hifastvpn.mac;
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "HiFastVPN-Mac-Pord";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
}; };
@ -748,10 +770,11 @@
CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = NJRRF427XB; DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=macosx*]" = NJRRF427XB;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = HiFastVPN; INFOPLIST_KEY_CFBundleDisplayName = HiFastVPN;
@ -762,6 +785,7 @@
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_BUNDLE_IDENTIFIER = com.taw.hifastvpn.mac; PRODUCT_BUNDLE_IDENTIFIER = com.taw.hifastvpn.mac;
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "HiFastVPN-Mac-Pord";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
}; };
name = Release; name = Release;

View File

@ -3,23 +3,19 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>com.apple.security.app-sandbox</key> <key>com.apple.security.app-sandbox</key>
<true/> <false/>
<key>com.apple.security.application-groups</key>
<array>
<string>$(TeamIdentifierPrefix)</string>
</array>
<key>com.apple.security.assets.pictures.read-write</key>
<true/>
<key>com.apple.security.personal-information.photos-library</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key> <key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/> <true/>
<key>com.apple.security.cs.allow-jit</key> <key>com.apple.security.cs.allow-jit</key>
<true/> <true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key> <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/> <true/>
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key> <key>com.apple.security.cs.disable-library-validation</key>
<true/> <true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.network.client</key> <key>com.apple.security.network.client</key>
<true/> <true/>
<key>com.apple.security.network.server</key> <key>com.apple.security.network.server</key>

View File

@ -3,19 +3,19 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>com.apple.security.app-sandbox</key> <key>com.apple.security.app-sandbox</key>
<true/> <false/>
<key>com.apple.security.assets.pictures.read-write</key>
<true/>
<key>com.apple.security.personal-information.photos-library</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key> <key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/> <true/>
<key>com.apple.security.cs.allow-jit</key> <key>com.apple.security.cs.allow-jit</key>
<true/> <true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key> <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/> <true/>
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key> <key>com.apple.security.cs.disable-library-validation</key>
<true/> <true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.network.client</key> <key>com.apple.security.network.client</key>
<true/> <true/>
<key>com.apple.security.network.server</key> <key>com.apple.security.network.server</key>

View File

@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts # In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix. # of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+102 version: 1.0.0+103
environment: environment:
sdk: ">=3.5.0 <4.0.0" sdk: ">=3.5.0 <4.0.0"