hi-client/lib/app/modules/kr_home/views/kr_home_view.dart

247 lines
11 KiB
Dart
Executable File

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:kaer_with_panels/app/modules/hi_menu/views/hi_menu_view.dart';
import 'package:kaer_with_panels/app/modules/kr_login/views/kr_login_view.dart';
import 'package:kaer_with_panels/app/common/app_run_data.dart';
import 'package:kaer_with_panels/app/widgets/hi_base_scaffold.dart';
import 'package:kaer_with_panels/app/widgets/kr_local_image.dart';
// import 'package:kaer_with_panels/app/widgets/kr_subscription_corner_button.dart';
import 'package:kaer_with_panels/app/widgets/dialogs/hi_dialog.dart';
import '../../../services/kr_subscribe_service.dart';
import '../controllers/kr_home_controller.dart';
import '../models/kr_home_views_status.dart';
import '../widgets/kr_home_map_view.dart';
import '../widgets/kr_subscribe_selector_view.dart';
import 'kr_home_bottom_panel.dart';
import 'kr_home_subscription_view.dart';
import './hi_animated_connect_button.dart';
import 'package:kaer_with_panels/app/services/global_overlay_service.dart';
import 'package:kaer_with_panels/app/widgets/swipe/has_swipe_config.dart';
import 'package:kaer_with_panels/app/widgets/swipe/swipe_config.dart';
import 'package:kaer_with_panels/app/routes/app_pages.dart';
class KRHomeView extends StatefulWidget implements HasSwipeConfig {
const KRHomeView({super.key});
@override
SwipeConfig get swipeConfig => SwipeConfig(
enableLeft: true,
enableRight: true,
onLeft: () {
Get.toNamed(Routes.HI_MENU);
},
onRight: () =>
GlobalOverlayService.instance.triggerSubscriptionAnimation(),
);
@override
State<KRHomeView> createState() => _KRHomeViewState();
}
class _KRHomeViewState extends State<KRHomeView> {
late KRHomeController controller;
@override
void initState() {
super.initState();
controller = Get.find<KRHomeController>();
}
@override
Widget build(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback((_) {
// ✅ 在 build 完成后操作 overlay/UI
if (Get.isRegistered<GlobalOverlayService>()) {
GlobalOverlayService.instance.updateSubscriptionButtonColor(null);
}
});
return Stack(
fit: StackFit.expand,
children: [
HIBaseScaffold(
showMenuButton: true,
topContentAreaHeight: 80,
child: Stack(
fit: StackFit.expand,
children: [
Align(
alignment: Alignment.topLeft,
child: SafeArea(
child: Padding(
padding: EdgeInsets.fromLTRB(40.w, 8.w, 0, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Hi快VPN-网在我在,网快我快',
style: TextStyle(
color: Colors.white,
fontSize: 14.sp,
fontWeight: FontWeight.w600,
),
),
// 订阅信息
Obx(() {
// 1. 先获取订阅信息
final currentSubscribe = controller
.kr_subscribeService.kr_currentSubscribe.value;
// 2. 准备一个 Widget 变量,用于存放最终要显示的内容
Widget content;
// --- 定义统一的文本样式,并设置行高 ---
final normalStyle = TextStyle(
color: Colors.white,
fontSize: 12.sp,
fontWeight: FontWeight.w600,
height: 1.2,
);
final highlightStyle = normalStyle.copyWith(
color: const Color(0xFFFF00B7),
);
// 3. 开始条件判断
if (currentSubscribe == null) {
// --- 情况1: 没有任何订阅信息 ---
content = Text(
'尚未购买套餐',
style: highlightStyle,
);
} else {
// --- 情况2: 有订阅信息,需要判断是否过期 ---
final now = DateTime.now();
DateTime? expireDateTime;
try {
expireDateTime =
DateTime.parse(currentSubscribe.expireTime);
} catch (e) {
// 日期格式解析失败
}
if (expireDateTime != null &&
expireDateTime.isBefore(now)) {
// --- 情况2.1: 订阅已过期 ---
final formattedExpireDate =
'${expireDateTime.year}/${expireDateTime.month.toString().padLeft(2, '0')}/${expireDateTime.day.toString().padLeft(2, '0')}';
// 使用换行符 \n 合并为单个 Text 组件
content = Text(
'您的套餐已于 $formattedExpireDate 到期\n请前往购买新套餐',
style: highlightStyle,
);
} else {
// --- 情况2.2: 订阅有效 ---
final difference =
expireDateTime?.difference(now);
final remainingDaysText =
(difference?.inDays ?? 0) > 0
? '${difference!.inDays}'
: '不足一天';
// 使用换行符 \n 合并为单个 Text 组件
content = Text(
'套餐剩余:$remainingDaysText\n${controller.kr_isConnected.value ? '当前线路:${controller.kr_getRealConnectedNodeCountry()}' : '未连接'}',
style: normalStyle,
);
}
}
// 4. 返回包裹在公共 Container 中的最终内容
return Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(top: 8.h),
child: content,
);
}),
SizedBox(height: 8.h), // 添加一些垂直间距
// --- 自定义“闪连”Checkbox ---
Obx(() {
return Row(
mainAxisSize: MainAxisSize.min, // 让 Row 的宽度包裹其内容
children: [
// --- 可点击的 Checkbox 区域 ---
GestureDetector(
// 点击方框和文字都可以切换状态
onTap: () => controller.toggleQuickConnect(
!controller.isQuickConnectEnabled.value),
child: AbsorbPointer(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
// 1. 自定义 Checkbox 的方框外观
Container(
width: 20,
height: 20,
decoration: BoxDecoration(
color: controller
.isQuickConnectEnabled.value
? Theme.of(context).primaryColor
: Colors.transparent,
border: Border.all(
color:
Theme.of(context).primaryColor,
width: 1.5,
),
borderRadius:
BorderRadius.circular(4.r),
),
child: controller
.isQuickConnectEnabled.value
? Icon(
Icons.check,
size: 14,
color: Colors.black,
)
: null,
),
SizedBox(width: 8),
// 2. “闪连”标签
Text(
'闪连',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.w600,
),
),
],
),
),
),
// --- 问号图标和点击弹窗区域 ---
SizedBox(width: 6), // 文字和问号图标之间的间距
GestureDetector(
onTap: () {
HIDialog.show(
title: '*闪连功能',
message:
'开启后,每次打开软件默认自动连接,无需点击连接按钮\n在后台关闭软件后,软件将自动断开',
);
},
child: KrLocalImage(
imageName: 'question-icon', // 图片名称
imageType: ImageType.svg, // 图片类型
width: 24,
height: 24,
color: Colors.white, // 让图标颜色与边框协调
),
),
],
);
}),
],
),
),
),
),
],
),
),
// 将 HIAnimatedConnectButton 移到 HIBaseScaffold 外部,避免 SafeArea 约束
HIAnimatedConnectButton(),
],
);
}
}