feat: 修改macos兼容
This commit is contained in:
parent
c058c2cea6
commit
9302764802
@ -157,8 +157,8 @@ class _KRHomeViewState extends State<KRHomeView> {
|
|||||||
children: [
|
children: [
|
||||||
// 1. 自定义 Checkbox 的方框外观
|
// 1. 自定义 Checkbox 的方框外观
|
||||||
Container(
|
Container(
|
||||||
width: 20.w,
|
width: 20,
|
||||||
height: 20.w,
|
height: 20,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: controller
|
color: controller
|
||||||
.isQuickConnectEnabled.value
|
.isQuickConnectEnabled.value
|
||||||
@ -176,18 +176,18 @@ class _KRHomeViewState extends State<KRHomeView> {
|
|||||||
.isQuickConnectEnabled.value
|
.isQuickConnectEnabled.value
|
||||||
? Icon(
|
? Icon(
|
||||||
Icons.check,
|
Icons.check,
|
||||||
size: 14.w,
|
size: 14,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
SizedBox(width: 8.w),
|
SizedBox(width: 8),
|
||||||
// 2. “闪连”标签
|
// 2. “闪连”标签
|
||||||
Text(
|
Text(
|
||||||
'闪连',
|
'闪连',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 20.sp,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -196,7 +196,7 @@ class _KRHomeViewState extends State<KRHomeView> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
// --- 问号图标和点击弹窗区域 ---
|
// --- 问号图标和点击弹窗区域 ---
|
||||||
SizedBox(width: 6.w), // 文字和问号图标之间的间距
|
SizedBox(width: 6), // 文字和问号图标之间的间距
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
HIDialog.show(
|
HIDialog.show(
|
||||||
@ -208,8 +208,8 @@ class _KRHomeViewState extends State<KRHomeView> {
|
|||||||
child: KrLocalImage(
|
child: KrLocalImage(
|
||||||
imageName: 'question-icon', // 图片名称
|
imageName: 'question-icon', // 图片名称
|
||||||
imageType: ImageType.svg, // 图片类型
|
imageType: ImageType.svg, // 图片类型
|
||||||
width: 24.w,
|
width: 24,
|
||||||
height: 24.w,
|
height: 24,
|
||||||
color: Colors.white, // 让图标颜色与边框协调
|
color: Colors.white, // 让图标颜色与边框协调
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -34,6 +34,7 @@ class KRInviteView extends GetView<KRInviteController> {
|
|||||||
children: [
|
children: [
|
||||||
// 🟢 第一行:奖励说明
|
// 🟢 第一行:奖励说明
|
||||||
Container(
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 20.w),
|
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 20.w),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).primaryColor,
|
color: Theme.of(context).primaryColor,
|
||||||
@ -41,7 +42,7 @@ class KRInviteView extends GetView<KRInviteController> {
|
|||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisSize: MainAxisSize.min, // 由内容撑开
|
mainAxisSize: MainAxisSize.max,
|
||||||
children: [
|
children: [
|
||||||
KrLocalImage(
|
KrLocalImage(
|
||||||
imageName: 'hi-home-logo',
|
imageName: 'hi-home-logo',
|
||||||
@ -204,4 +205,4 @@ class KRInviteView extends GetView<KRInviteController> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,9 +15,6 @@ import 'package:kaer_with_panels/app/widgets/dialogs/kr_dialog.dart';
|
|||||||
import 'package:kaer_with_panels/app/widgets/kr_local_image.dart';
|
import 'package:kaer_with_panels/app/widgets/kr_local_image.dart';
|
||||||
import 'package:kaer_with_panels/app/utils/kr_log_util.dart';
|
import 'package:kaer_with_panels/app/utils/kr_log_util.dart';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// 购买会员页面视图
|
/// 购买会员页面视图
|
||||||
class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController> {
|
class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController> {
|
||||||
@ -34,7 +31,7 @@ class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController> {
|
|||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(bottom: 80.w),
|
padding: EdgeInsets.only(bottom: 80.0),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
@ -67,52 +64,15 @@ class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController> {
|
|||||||
)
|
)
|
||||||
else
|
else
|
||||||
Container(
|
Container(
|
||||||
margin: EdgeInsets.symmetric(horizontal: 40.r),
|
margin: EdgeInsets.symmetric(horizontal: 40.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
// 套餐选择部分
|
// 套餐选择部分
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.all(0.r),
|
padding: EdgeInsets.all(0.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
// if (controller.kr_plans.length > 1)
|
|
||||||
// Container(
|
|
||||||
// height: 32.h,
|
|
||||||
// child: ListView.builder(
|
|
||||||
// scrollDirection: Axis.horizontal,
|
|
||||||
// padding: EdgeInsets.zero,
|
|
||||||
// itemCount: controller.kr_plans.length,
|
|
||||||
// itemBuilder: (context, index) {
|
|
||||||
// final plan = controller.kr_plans[index];
|
|
||||||
// final isSelected = index == controller.kr_selectedPlanIndex.value;
|
|
||||||
// return GestureDetector(
|
|
||||||
// onTap: () => controller.kr_selectPlan(index),
|
|
||||||
// child: Container(
|
|
||||||
// margin: EdgeInsets.only(right: 8.w),
|
|
||||||
// padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 4.h),
|
|
||||||
// decoration: BoxDecoration(
|
|
||||||
// color: isSelected ? Colors.white : Theme.of(context).cardColor,
|
|
||||||
// borderRadius: BorderRadius.circular(16.r),
|
|
||||||
// border: Border.all(
|
|
||||||
// color: isSelected ? Colors.white : Colors.grey.withOpacity(0.3),
|
|
||||||
// width: 1,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// child: Center(
|
|
||||||
// child: Text(
|
|
||||||
// plan.kr_name,
|
|
||||||
// style: KrAppTextStyle(
|
|
||||||
// fontSize: 13,
|
|
||||||
// color: isSelected ? Colors.white : Theme.of(context).textTheme.bodyMedium?.color,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
Column(
|
Column(
|
||||||
// 使用 List.generate 动态创建卡片列表
|
// 使用 List.generate 动态创建卡片列表
|
||||||
children: List.generate(
|
children: List.generate(
|
||||||
@ -130,12 +90,9 @@ class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController> {
|
|||||||
// 使用 Padding 来为每个卡片添加底部的间距,模拟 mainAxisSpacing
|
// 使用 Padding 来为每个卡片添加底部的间距,模拟 mainAxisSpacing
|
||||||
return Padding(
|
return Padding(
|
||||||
padding:
|
padding:
|
||||||
EdgeInsets.only(bottom: 8.h),
|
EdgeInsets.only(bottom: 8.0),
|
||||||
// 👇 核心改动:父节点 SizedBox 决定了卡片的高度
|
child: SizedBox(
|
||||||
child: ConstrainedBox(
|
height: 140.0,
|
||||||
constraints: BoxConstraints(
|
|
||||||
minHeight: 100.h, // 设置最小高度为 100.h
|
|
||||||
),
|
|
||||||
child: _kr_buildPlanOptionCard(
|
child: _kr_buildPlanOptionCard(
|
||||||
plan,
|
plan,
|
||||||
controller
|
controller
|
||||||
@ -152,394 +109,15 @@ class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
/* SizedBox(height: 16.h),
|
|
||||||
// 套餐描述部分
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.all(16.r),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context).cardColor,
|
|
||||||
borderRadius: BorderRadius.circular(16.r),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: Colors.black.withOpacity(0.05),
|
|
||||||
blurRadius: 10,
|
|
||||||
offset: Offset(0, 4),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
AppTranslations.kr_purchaseMembership.packageDescription,
|
|
||||||
style: KrAppTextStyle(
|
|
||||||
fontSize: 15,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Theme.of(context).textTheme.bodyMedium?.color,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 16.h),
|
|
||||||
Obx(() {
|
|
||||||
final featureLabels = controller.kr_getSelectedPlanFeatureLabels();
|
|
||||||
final features = controller.kr_getSelectedPlanFeatures();
|
|
||||||
final isExpanded = controller.kr_isDescriptionExpanded.value;
|
|
||||||
final selectedPlan = controller.kr_plans[controller.kr_selectedPlanIndex.value];
|
|
||||||
|
|
||||||
// 添加流量和设备限制信息
|
|
||||||
final trafficAndDeviceInfo = Padding(
|
|
||||||
padding: EdgeInsets.only(bottom: 8.h),
|
|
||||||
child: Container(
|
|
||||||
width: double.infinity,
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
horizontal: 12.w,
|
|
||||||
vertical: 8.h,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context).cardColor,
|
|
||||||
borderRadius: BorderRadius.circular(12.r),
|
|
||||||
border: Border.all(
|
|
||||||
color: Colors.grey.withOpacity(0.2),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'${AppTranslations.kr_purchaseMembership.trafficLimit}:${controller.kr_getTrafficLimitText(selectedPlan)}',
|
|
||||||
style: KrAppTextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
color: Theme.of(context).textTheme.bodyMedium?.color,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 4.h),
|
|
||||||
Text(
|
|
||||||
'${AppTranslations.kr_purchaseMembership.deviceLimit}:${controller.kr_getDeviceLimitText(selectedPlan)}',
|
|
||||||
style: KrAppTextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
color: Theme.of(context).textTheme.bodyMedium?.color,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
// if (featureLabels.isEmpty) {
|
|
||||||
// return Column(
|
|
||||||
// children: [
|
|
||||||
// trafficAndDeviceInfo,
|
|
||||||
// Center(
|
|
||||||
// child: Padding(
|
|
||||||
// padding: EdgeInsets.symmetric(vertical: 16.h),
|
|
||||||
// child: Text(
|
|
||||||
// AppTranslations.kr_purchaseMembership.noData,
|
|
||||||
// style: KrAppTextStyle(
|
|
||||||
// fontSize: 14,
|
|
||||||
// color: Theme.of(context).textTheme.bodySmall?.color,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
final displayCount = isExpanded ? featureLabels.length : (featureLabels.length > 3 ? 3 : featureLabels.length);
|
|
||||||
|
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
trafficAndDeviceInfo,
|
|
||||||
...List.generate(displayCount, (index) {
|
|
||||||
final feature = features[index];
|
|
||||||
return Padding(
|
|
||||||
padding: EdgeInsets.only(bottom: 8.h),
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
Get.dialog(
|
|
||||||
Dialog(
|
|
||||||
backgroundColor: Theme.of(Get.context!).cardColor,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(16.r),
|
|
||||||
),
|
|
||||||
child: Padding(
|
|
||||||
padding: EdgeInsets.all(16.r),
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
feature.kr_label,
|
|
||||||
style: KrAppTextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Theme.of(Get.context!).textTheme.bodyMedium?.color,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 8.h),
|
|
||||||
if (feature.kr_details.isNotEmpty)
|
|
||||||
...feature.kr_details.map((detail) => Padding(
|
|
||||||
padding: EdgeInsets.only(bottom: 8.h),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
if (detail.kr_label.isNotEmpty) ...[
|
|
||||||
Text(
|
|
||||||
detail.kr_label,
|
|
||||||
style: KrAppTextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Theme.of(Get.context!).textTheme.bodyMedium?.color,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 4.h),
|
|
||||||
],
|
|
||||||
Text(
|
|
||||||
detail.kr_description,
|
|
||||||
style: KrAppTextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
color: Theme.of(Get.context!).textTheme.bodySmall?.color,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)).toList(),
|
|
||||||
SizedBox(height: 16.h),
|
|
||||||
Align(
|
|
||||||
alignment: Alignment.centerRight,
|
|
||||||
child: TextButton(
|
|
||||||
onPressed: () => Get.back(),
|
|
||||||
child: Text(
|
|
||||||
AppTranslations.kr_dialog.kr_ok,
|
|
||||||
style: KrAppTextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
width: double.infinity,
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
horizontal: 12.w,
|
|
||||||
vertical: 8.h,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(Get.context!).cardColor,
|
|
||||||
borderRadius: BorderRadius.circular(12.r),
|
|
||||||
border: Border.all(
|
|
||||||
color: Colors.grey.withOpacity(0.2),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
featureLabels[index],
|
|
||||||
style: KrAppTextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
color: Theme.of(Get.context!).textTheme.bodyMedium?.color,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.all(4.r),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white.withOpacity(0.1),
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
),
|
|
||||||
child: Icon(
|
|
||||||
Icons.info_outline,
|
|
||||||
size: 16.r,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
if (featureLabels.length > 3)
|
|
||||||
GestureDetector(
|
|
||||||
onTap: () => controller.kr_toggleDescriptionExpanded(),
|
|
||||||
child: Padding(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 4.h),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
isExpanded
|
|
||||||
? AppTranslations.kr_purchaseMembership.collapse
|
|
||||||
: AppTranslations.kr_purchaseMembership.expand,
|
|
||||||
style: KrAppTextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(width: 4.w),
|
|
||||||
Icon(
|
|
||||||
isExpanded ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down,
|
|
||||||
size: 16.r,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 16.h),
|
|
||||||
// 支付方式选择部分
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.all(16.r),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context).cardColor,
|
|
||||||
borderRadius: BorderRadius.circular(16.r),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: Colors.black.withOpacity(0.05),
|
|
||||||
blurRadius: 10,
|
|
||||||
offset: Offset(0, 4),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
AppTranslations.kr_purchaseMembership.paymentMethod,
|
|
||||||
style: KrAppTextStyle(
|
|
||||||
fontSize: 15,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Theme.of(context).textTheme.bodyMedium?.color,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 16.h),
|
|
||||||
Obx(() => ListView.separated(
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
shrinkWrap: true,
|
|
||||||
physics: NeverScrollableScrollPhysics(),
|
|
||||||
itemCount: controller.kr_paymentMethods.length,
|
|
||||||
separatorBuilder: (context, index) => Divider(
|
|
||||||
height: 1.w,
|
|
||||||
indent: 44.w,
|
|
||||||
color: Theme.of(context).dividerColor.withOpacity(0.1),
|
|
||||||
),
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
final paymentMethod = controller.kr_paymentMethods[index];
|
|
||||||
return InkWell(
|
|
||||||
onTap: () => controller.kr_selectPaymentMethod(index),
|
|
||||||
child: Container(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 12.r, horizontal: 16.r),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: 32.w,
|
|
||||||
height: 32.w,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white.withOpacity(0.1),
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: paymentMethod.icon.isNotEmpty
|
|
||||||
? KRNetworkImage(
|
|
||||||
kr_imageUrl: paymentMethod.icon,
|
|
||||||
kr_width: 20.w,
|
|
||||||
kr_height: 20.w,
|
|
||||||
kr_placeholder: SizedBox(
|
|
||||||
width: 20.w,
|
|
||||||
height: 20.w,
|
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 2,
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
kr_errorWidget: Icon(
|
|
||||||
Icons.payment_rounded,
|
|
||||||
size: 20.w,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: Icon(
|
|
||||||
Icons.payment_rounded,
|
|
||||||
size: 20.w,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(width: 12.w),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
controller.kr_getPaymentMethodTitle(paymentMethod),
|
|
||||||
style: KrAppTextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
color: Theme.of(context).textTheme.bodyMedium?.color,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Obx(() {
|
|
||||||
final isSelected = index == controller.kr_selectedPaymentMethodIndex.value;
|
|
||||||
return Container(
|
|
||||||
width: 24.w,
|
|
||||||
height: 24.w,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: isSelected ? Colors.white : Colors.transparent,
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
border: Border.all(
|
|
||||||
color: isSelected ? Colors.white : Colors.grey.withOpacity(0.3),
|
|
||||||
width: 1.5,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: isSelected
|
|
||||||
? Icon(
|
|
||||||
Icons.check,
|
|
||||||
color: Colors.white,
|
|
||||||
size: 16.r,
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),*/
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
|
|
||||||
|
|
||||||
Positioned(
|
Positioned(
|
||||||
top: 160.w, // 距离顶部的距离
|
top: 160.0, // 距离顶部的距离
|
||||||
right: 10.w, // 固定在右侧 20.w 的位置
|
right: 10.0, // 固定在右侧 20.w 的位置
|
||||||
child: KrLocalImage(
|
child: KrLocalImage(
|
||||||
imageName: 'purchase_slogan',
|
imageName: 'purchase_slogan',
|
||||||
imageType: ImageType.svg,
|
imageType: ImageType.svg,
|
||||||
@ -572,12 +150,12 @@ class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController> {
|
|||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
Obx(() => Text(
|
Obx(() => Text(
|
||||||
controller.kr_userEmail.value,
|
controller.kr_userEmail.value,
|
||||||
style: KrAppTextStyle(
|
style: KrAppTextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
color: Theme.of(context).textTheme.bodySmall?.color,
|
color: Theme.of(context).textTheme.bodySmall?.color,
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -585,11 +163,12 @@ class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController> {
|
|||||||
|
|
||||||
// 套餐选项卡片
|
// 套餐选项卡片
|
||||||
Widget _kr_buildPlanOptionCard(
|
Widget _kr_buildPlanOptionCard(
|
||||||
KRPackageListItem plan,
|
KRPackageListItem plan,
|
||||||
int planIndex,
|
int planIndex,
|
||||||
int? discountIndex,
|
int? discountIndex,
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
bool isFirst,) {
|
bool isFirst,
|
||||||
|
) {
|
||||||
// 由于移除了 Obx,isSelected 的值在构建时就固定了。
|
// 由于移除了 Obx,isSelected 的值在构建时就固定了。
|
||||||
// 它将不再响应用户的点击事件来改变UI。
|
// 它将不再响应用户的点击事件来改变UI。
|
||||||
// 根据您的要求,isSelected 的值与 isFirst 相反。
|
// 根据您的要求,isSelected 的值与 isFirst 相反。
|
||||||
@ -606,25 +185,27 @@ class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController> {
|
|||||||
padding: EdgeInsets.all(5), // 边框宽度
|
padding: EdgeInsets.all(5), // 边框宽度
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.black, // 边框颜色
|
color: Colors.black, // 边框颜色
|
||||||
borderRadius: BorderRadius.circular(43.r), // 外部圆角 = 内部圆角 + 边框宽度
|
borderRadius: BorderRadius.circular(43.0), // 外部圆角 = 内部圆角 + 边框宽度
|
||||||
),
|
),
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(38.r), // 内部圆角
|
borderRadius: BorderRadius.circular(38.0), // 内部圆角
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.fromLTRB(45.w, 10.w, 0.w, 10.w),
|
padding: EdgeInsets.fromLTRB(45.0, 10.0, 0.0, 10.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: isSelected ? Colors.black : Theme.of(context).primaryColor,
|
color: isSelected ? Colors.black : Theme.of(context).primaryColor,
|
||||||
borderRadius: BorderRadius.circular(38.r),
|
borderRadius: BorderRadius.circular(38.0),
|
||||||
),
|
),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
children: [
|
children: [
|
||||||
Column( mainAxisSize: MainAxisSize.min,
|
Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
controller.kr_getTimeStr(plan, discountIndex: discountIndex),
|
controller.kr_getTimeStr(plan,
|
||||||
|
discountIndex: discountIndex),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 24,
|
fontSize: 24,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@ -642,8 +223,7 @@ class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController> {
|
|||||||
color: isSelected
|
color: isSelected
|
||||||
? Colors.white
|
? Colors.white
|
||||||
: Theme.of(context).textTheme.bodyMedium?.color,
|
: Theme.of(context).textTheme.bodyMedium?.color,
|
||||||
)
|
)),
|
||||||
),
|
|
||||||
Text(
|
Text(
|
||||||
'约¥${controller.kr_getDayPlanPrice(plan, discountIndex: discountIndex).toStringAsFixed(2)}/天',
|
'约¥${controller.kr_getDayPlanPrice(plan, discountIndex: discountIndex).toStringAsFixed(2)}/天',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
@ -652,12 +232,9 @@ class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController> {
|
|||||||
color: isSelected
|
color: isSelected
|
||||||
? Colors.white
|
? Colors.white
|
||||||
: Theme.of(context).textTheme.bodyMedium?.color,
|
: Theme.of(context).textTheme.bodyMedium?.color,
|
||||||
)
|
)),
|
||||||
),
|
]),
|
||||||
]
|
if (!isFirst)
|
||||||
),
|
|
||||||
|
|
||||||
if(!isFirst)
|
|
||||||
Positioned(
|
Positioned(
|
||||||
top: 0,
|
top: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
@ -665,9 +242,9 @@ class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController> {
|
|||||||
angle: 0.785398, // 45度角 (π/4)
|
angle: 0.785398, // 45度角 (π/4)
|
||||||
child: Container(
|
child: Container(
|
||||||
// 调整位置,让标签的一部分显示在容器外
|
// 调整位置,让标签的一部分显示在容器外
|
||||||
transform: Matrix4.translationValues(19.w, -12.w, 0),
|
transform: Matrix4.translationValues(30, -10, 0),
|
||||||
width: 92.w, // 适当的宽度
|
width: 130, // 适当的宽度
|
||||||
height: 16.w, // 固定高度
|
height: 20, // 固定高度
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).primaryColor, // 使用主题色作为背景
|
color: Theme.of(context).primaryColor, // 使用主题色作为背景
|
||||||
),
|
),
|
||||||
@ -685,47 +262,6 @@ class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
/* if (discountIndex != null && plan.kr_discount.isNotEmpty) ...[
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
horizontal: 8.w,
|
|
||||||
vertical: 2.h
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: plan.kr_discount[discountIndex].kr_discount < 100
|
|
||||||
? Colors.red.withOpacity(0.08)
|
|
||||||
: Colors.transparent,
|
|
||||||
borderRadius: BorderRadius.circular(4.r),
|
|
||||||
border: plan.kr_discount[discountIndex].kr_discount < 100
|
|
||||||
? Border.all(
|
|
||||||
color: Colors.red.withOpacity(0.2),
|
|
||||||
width: 1,
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
boxShadow: plan.kr_discount[discountIndex].kr_discount < 100
|
|
||||||
? [
|
|
||||||
BoxShadow(
|
|
||||||
color: Colors.red.withOpacity(0.05),
|
|
||||||
blurRadius: 4,
|
|
||||||
offset: Offset(0, 2),
|
|
||||||
spreadRadius: 0,
|
|
||||||
),
|
|
||||||
]
|
|
||||||
: null,
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
controller.kr_getDiscountText(plan, discountIndex),
|
|
||||||
style: KrAppTextStyle(
|
|
||||||
fontSize: 10,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: plan.kr_discount[discountIndex].kr_discount < 100
|
|
||||||
? Colors.red.withOpacity(0.9)
|
|
||||||
: Colors.transparent,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],*/
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -733,56 +269,4 @@ class KRPurchaseMembershipView extends GetView<KRPurchaseMembershipController> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 底部部分
|
|
||||||
Widget _kr_buildBottomSection(BuildContext context) {
|
|
||||||
// 如果正在加载或没有数据,不显示底部按钮
|
|
||||||
if (controller.kr_isLoading.value || controller.kr_plans.isEmpty || controller.kr_paymentMethods.isEmpty) {
|
|
||||||
return SizedBox.shrink();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
padding: EdgeInsets.all(16.r),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context).scaffoldBackgroundColor,
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: Colors.black.withOpacity(0.05),
|
|
||||||
offset: Offset(0, -2),
|
|
||||||
blurRadius: 8,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: SizedBox(
|
|
||||||
width: double.infinity,
|
|
||||||
child: ElevatedButton(
|
|
||||||
onPressed: () {
|
|
||||||
KRDialog.show(
|
|
||||||
title: AppTranslations.kr_purchaseMembership.confirmPurchase,
|
|
||||||
message: AppTranslations.kr_purchaseMembership.confirmPurchaseDesc,
|
|
||||||
cancelText: AppTranslations.kr_dialog.kr_cancel,
|
|
||||||
confirmText: AppTranslations.kr_dialog.kr_confirm,
|
|
||||||
onConfirm: () => controller.kr_startSubscription(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: Colors.white,
|
|
||||||
foregroundColor: Colors.white,
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 12.h),
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8.r),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
controller.kr_getSubscribeButtonText(),
|
|
||||||
style: KrAppTextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,7 @@ class KRSecureStorage {
|
|||||||
|
|
||||||
// 存储箱名称
|
// 存储箱名称
|
||||||
static const String _boxName = 'kaer_secure_storage';
|
static const String _boxName = 'kaer_secure_storage';
|
||||||
|
|
||||||
// 加密密钥
|
// 加密密钥
|
||||||
static const String _encryptionKey = 'kaer_secure_storage_key';
|
static const String _encryptionKey = 'kaer_secure_storage_key';
|
||||||
|
|
||||||
@ -27,19 +27,19 @@ class KRSecureStorage {
|
|||||||
if (Platform.isMacOS || Platform.isWindows || Platform.isLinux) {
|
if (Platform.isMacOS || Platform.isWindows || Platform.isLinux) {
|
||||||
final baseDir = await getApplicationSupportDirectory();
|
final baseDir = await getApplicationSupportDirectory();
|
||||||
KRLogUtil.kr_i('初始化 Hive,路径: ${baseDir.path}', tag: 'SecureStorage');
|
KRLogUtil.kr_i('初始化 Hive,路径: ${baseDir.path}', tag: 'SecureStorage');
|
||||||
|
|
||||||
// 确保目录存在
|
// 确保目录存在
|
||||||
if (!baseDir.existsSync()) {
|
if (!baseDir.existsSync()) {
|
||||||
await baseDir.create(recursive: true);
|
await baseDir.create(recursive: true);
|
||||||
KRLogUtil.kr_i('已创建 Hive 目录: ${baseDir.path}', tag: 'SecureStorage');
|
KRLogUtil.kr_i('已创建 Hive 目录: ${baseDir.path}', tag: 'SecureStorage');
|
||||||
}
|
}
|
||||||
|
|
||||||
await Hive.initFlutter(baseDir.path);
|
await Hive.initFlutter(baseDir.path);
|
||||||
} else {
|
} else {
|
||||||
// Android 和 iOS 使用默认路径
|
// Android 和 iOS 使用默认路径
|
||||||
await Hive.initFlutter();
|
await Hive.initFlutter();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用加密适配器
|
// 使用加密适配器
|
||||||
final key = HiveAesCipher(_generateKey());
|
final key = HiveAesCipher(_generateKey());
|
||||||
await Hive.openBox(_boxName, encryptionCipher: key);
|
await Hive.openBox(_boxName, encryptionCipher: key);
|
||||||
@ -48,14 +48,14 @@ class KRSecureStorage {
|
|||||||
KRLogUtil.kr_e('初始化 Hive 失败: $e', tag: 'SecureStorage');
|
KRLogUtil.kr_e('初始化 Hive 失败: $e', tag: 'SecureStorage');
|
||||||
KRLogUtil.kr_e('错误类型: ${e.runtimeType}', tag: 'SecureStorage');
|
KRLogUtil.kr_e('错误类型: ${e.runtimeType}', tag: 'SecureStorage');
|
||||||
KRLogUtil.kr_e('错误堆栈: $stackTrace', tag: 'SecureStorage');
|
KRLogUtil.kr_e('错误堆栈: $stackTrace', tag: 'SecureStorage');
|
||||||
|
|
||||||
// 对于 Windows 和 Linux,如果初始化失败,尝试删除旧文件并重试
|
// 对于 Windows 和 Linux,如果初始化失败,尝试删除旧文件并重试
|
||||||
if (Platform.isWindows || Platform.isLinux) {
|
if (Platform.isWindows || Platform.isLinux) {
|
||||||
try {
|
try {
|
||||||
KRLogUtil.kr_i('尝试清理并重新初始化 Hive', tag: 'SecureStorage');
|
KRLogUtil.kr_i('尝试清理并重新初始化 Hive', tag: 'SecureStorage');
|
||||||
final baseDir = await getApplicationSupportDirectory();
|
final baseDir = await getApplicationSupportDirectory();
|
||||||
final hiveDir = Directory(baseDir.path);
|
final hiveDir = Directory(baseDir.path);
|
||||||
|
|
||||||
// 查找并删除相关的 Hive 文件
|
// 查找并删除相关的 Hive 文件
|
||||||
if (hiveDir.existsSync()) {
|
if (hiveDir.existsSync()) {
|
||||||
final files = hiveDir.listSync();
|
final files = hiveDir.listSync();
|
||||||
@ -63,8 +63,8 @@ class KRSecureStorage {
|
|||||||
if (entity is File) {
|
if (entity is File) {
|
||||||
final fileName = entity.path.split(Platform.pathSeparator).last;
|
final fileName = entity.path.split(Platform.pathSeparator).last;
|
||||||
// 删除 Hive 数据库文件(通常是 .hive 或 .lock 文件)
|
// 删除 Hive 数据库文件(通常是 .hive 或 .lock 文件)
|
||||||
if (fileName.startsWith(_boxName) ||
|
if (fileName.startsWith(_boxName) ||
|
||||||
fileName.endsWith('.hive') ||
|
fileName.endsWith('.hive') ||
|
||||||
fileName.endsWith('.lock')) {
|
fileName.endsWith('.lock')) {
|
||||||
try {
|
try {
|
||||||
await entity.delete();
|
await entity.delete();
|
||||||
@ -76,7 +76,7 @@ class KRSecureStorage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重新初始化
|
// 重新初始化
|
||||||
await Hive.initFlutter(baseDir.path);
|
await Hive.initFlutter(baseDir.path);
|
||||||
final key = HiveAesCipher(_generateKey());
|
final key = HiveAesCipher(_generateKey());
|
||||||
@ -116,8 +116,15 @@ class KRSecureStorage {
|
|||||||
try {
|
try {
|
||||||
final box = await _ensureBoxOpen();
|
final box = await _ensureBoxOpen();
|
||||||
await box.put(key, value);
|
await box.put(key, value);
|
||||||
|
|
||||||
|
// 🔧 关键修复:强制将数据立即写入磁盘,确保持久化
|
||||||
|
// 不调用 flush() 时,数据只在内存缓冲区中,应用关闭后会丢失!
|
||||||
|
await box.flush();
|
||||||
|
|
||||||
|
print('💾 [SecureStorage] 数据已保存并刷新到磁盘: $key');
|
||||||
KRLogUtil.kr_i('✅ 数据已保存: $key', tag: 'SecureStorage');
|
KRLogUtil.kr_i('✅ 数据已保存: $key', tag: 'SecureStorage');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
print('❌ [SecureStorage] 存储数据失败: $e');
|
||||||
KRLogUtil.kr_e('❌ 存储数据失败: $e', tag: 'SecureStorage');
|
KRLogUtil.kr_e('❌ 存储数据失败: $e', tag: 'SecureStorage');
|
||||||
rethrow; // 重新抛出异常,让调用者知道保存失败
|
rethrow; // 重新抛出异常,让调用者知道保存失败
|
||||||
}
|
}
|
||||||
@ -210,4 +217,4 @@ class KRSecureStorage {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@ class KRWindowManager with WindowListener, TrayListener {
|
|||||||
// 阻止窗口关闭
|
// 阻止窗口关闭
|
||||||
await windowManager.setPreventClose(true);
|
await windowManager.setPreventClose(true);
|
||||||
} else {
|
} else {
|
||||||
await windowManager.setTitle('Kaer VPN');
|
await windowManager.setTitle('HiFastVPN');
|
||||||
await windowManager.setSize(const Size(800, 668));
|
await windowManager.setSize(const Size(800, 668));
|
||||||
await windowManager.setMinimumSize(const Size(400, 334));
|
await windowManager.setMinimumSize(const Size(400, 334));
|
||||||
await windowManager.center();
|
await windowManager.center();
|
||||||
@ -94,7 +94,7 @@ class KRWindowManager with WindowListener, TrayListener {
|
|||||||
/// 初始化平台通道
|
/// 初始化平台通道
|
||||||
void _initPlatformChannel() {
|
void _initPlatformChannel() {
|
||||||
if (Platform.isMacOS) {
|
if (Platform.isMacOS) {
|
||||||
const platform = MethodChannel('kaer_vpn/terminate');
|
const platform = MethodChannel('hifast_vpn/terminate');
|
||||||
platform.setMethodCallHandler((call) async {
|
platform.setMethodCallHandler((call) async {
|
||||||
if (call.method == 'onTerminate') {
|
if (call.method == 'onTerminate') {
|
||||||
KRLogUtil.kr_i('收到应用终止通知');
|
KRLogUtil.kr_i('收到应用终止通知');
|
||||||
|
|||||||
@ -571,11 +571,10 @@
|
|||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
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*]" = "Developer ID Application";
|
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Manual;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = NJRRF427XB;
|
||||||
"DEVELOPMENT_TEAM[sdk=macosx*]" = NJRRF427XB;
|
|
||||||
ENABLE_HARDENED_RUNTIME = NO;
|
ENABLE_HARDENED_RUNTIME = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = HiFastVPN;
|
INFOPLIST_KEY_CFBundleDisplayName = HiFastVPN;
|
||||||
@ -586,7 +585,6 @@
|
|||||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||||
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*]" = "";
|
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
};
|
};
|
||||||
name = Profile;
|
name = Profile;
|
||||||
@ -706,11 +704,10 @@
|
|||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
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*]" = "Developer ID Application";
|
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Manual;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = NJRRF427XB;
|
||||||
"DEVELOPMENT_TEAM[sdk=macosx*]" = NJRRF427XB;
|
|
||||||
ENABLE_HARDENED_RUNTIME = NO;
|
ENABLE_HARDENED_RUNTIME = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = HiFastVPN;
|
INFOPLIST_KEY_CFBundleDisplayName = HiFastVPN;
|
||||||
@ -721,7 +718,6 @@
|
|||||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||||
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*]" = "";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
};
|
};
|
||||||
@ -735,11 +731,10 @@
|
|||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
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*]" = "Developer ID Application";
|
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Manual;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = NJRRF427XB;
|
||||||
"DEVELOPMENT_TEAM[sdk=macosx*]" = NJRRF427XB;
|
|
||||||
ENABLE_HARDENED_RUNTIME = NO;
|
ENABLE_HARDENED_RUNTIME = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = HiFastVPN;
|
INFOPLIST_KEY_CFBundleDisplayName = HiFastVPN;
|
||||||
@ -750,7 +745,6 @@
|
|||||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||||
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*]" = "";
|
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
|
|||||||
@ -37,7 +37,7 @@ class AppDelegate: FlutterAppDelegate {
|
|||||||
|
|
||||||
// 通知 Flutter 端应用即将终止
|
// 通知 Flutter 端应用即将终止
|
||||||
if let controller = NSApp.windows.first?.contentViewController as? FlutterViewController {
|
if let controller = NSApp.windows.first?.contentViewController as? FlutterViewController {
|
||||||
let channel = FlutterMethodChannel(name: "kaer_vpn/terminate", binaryMessenger: controller.engine.binaryMessenger)
|
let channel = FlutterMethodChannel(name: "hifast_vpn/terminate", binaryMessenger: controller.engine.binaryMessenger)
|
||||||
channel.invokeMethod("onTerminate", arguments: nil)
|
channel.invokeMethod("onTerminate", arguments: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user