home_view.dart 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. import 'dart:io';
  2. import 'package:flutter/foundation.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:get/get.dart';
  5. import 'package:naiyouwl/app/common/constants.dart';
  6. import 'package:naiyouwl/app/component/button_select.dart';
  7. import 'package:naiyouwl/app/component/connection_status.dart';
  8. import 'package:naiyouwl/app/component/connection_widget.dart';
  9. import 'package:naiyouwl/app/component/sys_app_bar.dart';
  10. import 'package:naiyouwl/app/controller/controllers.dart';
  11. import 'package:naiyouwl/app/utils/system_proxy.dart';
  12. import 'package:url_launcher/url_launcher.dart';
  13. import '../controllers/home_controller.dart';
  14. class HomeView extends GetView<HomeController> {
  15. const HomeView({Key? key}) : super(key: key);
  16. @override
  17. Widget build(BuildContext context) {
  18. return Container(
  19. decoration: const BoxDecoration(
  20. image: DecorationImage(
  21. image: AssetImage("assets/images/main/main.png"),
  22. fit: BoxFit.fill,
  23. ),
  24. ),
  25. child: Scaffold(
  26. backgroundColor: Colors.transparent,
  27. appBar: SysAppBar(title: const Text("首页"), actions: [
  28. Row(
  29. children: [
  30. IconButton(
  31. icon: const Icon(Icons.refresh),
  32. tooltip: '刷新节点',
  33. onPressed: () {
  34. controller.fetchNode();
  35. },
  36. ),
  37. IconButton(onPressed: (){
  38. controller.outlogin();
  39. } ,tooltip: '切换账号', icon: const Icon(Icons.exit_to_app))
  40. ],
  41. ),
  42. ],),
  43. body: Obx(() {
  44. if (controllers.global.errorMsg.isNotEmpty) {
  45. // WidgetsBinding.instance.addPostFrameCallback((_) {
  46. // ScaffoldMessenger.of(context).showSnackBar(
  47. // SnackBar(content: Text(controller.errorMsg.value))
  48. // );
  49. // });
  50. String message = controllers.global.errorMsg.value;
  51. controllers.global.errorMsg.value = ''; // Clear the error message immediately
  52. // Show the dialog and wait for the result
  53. Future.delayed(Duration.zero, () async {
  54. bool? result = await controllers.dialog.showNormalDialog(
  55. title: "提示",
  56. content: message,
  57. cancelText: "取消",
  58. enterText: "确认",
  59. );
  60. if (result != null && result) {
  61. // User pressed "确认"
  62. if(controllers.global.statusCode.value == 445){
  63. await launchUrl(Uri.parse(controller.UsersysConfig.value.userBuy ?? ""));
  64. }
  65. } else {
  66. // User pressed "取消" or dismissed the dialog
  67. }
  68. });
  69. }
  70. final disabled = !controllers.service.isRunning;
  71. return controller.isLoading.value ? const Center(
  72. child: CircularProgressIndicator()) : Column(
  73. children: [
  74. // 错误消息展示
  75. UserStatusWidget(
  76. isActive: controller.GetEnable(),
  77. isLoading: controller.isLoading.value,
  78. username: controller.GetUserName(),
  79. expiryDate: controller.GetExpiredAt(),
  80. userTraffic: controller.GetTraffic(),
  81. onRefresh: () async {
  82. // 这里插入刷新操作代码
  83. //await Future.delayed(Duration(seconds: 2));
  84. if (controller.isLoading.value != true) {
  85. controller.fetchUserinfo();
  86. }
  87. },),
  88. Padding(
  89. padding: const EdgeInsets.fromLTRB(20, 20, 0, 0),
  90. child: Row(
  91. children: controller.imageMap.entries.expand((entry) {
  92. return [
  93. GestureDetector(
  94. onTap: () => controller.onImageTap(entry.key),
  95. child: Image(
  96. image: AssetImage(entry.value),
  97. width: 60,
  98. height: 60,
  99. ),
  100. ),
  101. //Spacer(), // 平均分配间隔
  102. const SizedBox(width: 30),
  103. ];
  104. }).toList()
  105. ..removeLast(), // 删除最后一个Spacer
  106. )
  107. ),
  108. const SizedBox(height: 30,),
  109. Padding(
  110. padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
  111. child: Row(
  112. children: [
  113. Text(controller.getHttp().toString()),
  114. const Spacer(),
  115. Text(controller.getSocket().toString()),
  116. ],
  117. ),
  118. ),
  119. ConnectionWidget(
  120. status: controller.connectStatus.value, onTap: () {
  121. if(controller.isRunning){
  122. controller.stopVpn();
  123. } else
  124. {
  125. controller.fetchAuthUser();
  126. }
  127. },),
  128. Align(
  129. alignment: Alignment.center,
  130. child: Text(controllers.global.msgStatus.value),
  131. ),
  132. const SizedBox(height: 20,),
  133. Padding(
  134. padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
  135. child: SizedBox(
  136. width: 200,
  137. height: 40,
  138. child: ElevatedButton(
  139. onPressed: () {
  140. controller.RouteNode();
  141. },
  142. style: ElevatedButton.styleFrom(
  143. primary: Colors.white, // 设置背景颜色为白色
  144. onPrimary: Colors.black, // 设置文字颜色为黑色,确保在白色背景上可见
  145. shape: RoundedRectangleBorder(
  146. borderRadius: BorderRadius.circular(20), // 设置圆角
  147. ),
  148. ),
  149. child: Text(controller.GetNode()),
  150. ),
  151. ),
  152. ),
  153. const SizedBox(height: 40,),
  154. Center(
  155. child: Row(
  156. mainAxisAlignment: MainAxisAlignment.center,
  157. children: [
  158. ButtonSelect(
  159. labels: ['setting_mode_rules'.tr,'setting_mode_global'.tr,],
  160. value: controllers.global.modes.indexOf(controllers.global.modesSelect.value),
  161. onSelect: (idx) => {
  162. controllers.global.updateMode(controllers.global.modes[idx])
  163. },
  164. ),
  165. // const SizedBox(width: 10,),
  166. // ButtonSelect(
  167. // labels: ['route_sys_tile'.tr,'route_tun_title'.tr,],
  168. // value: controllers.global.routeModes.indexOf(controllers.global.routeModesSelect.value),
  169. // onSelect: (idx) => {
  170. // controllers.global.updateRoute(controllers.global.routeModes[idx])
  171. // }
  172. // ),
  173. ],
  174. ),
  175. ),
  176. controllers.service.serviceMode.value == true ? Padding(
  177. padding: const EdgeInsets.fromLTRB(60, 10, 50, 0),
  178. child: Row(
  179. mainAxisAlignment: MainAxisAlignment.center,
  180. children: [
  181. ElevatedButton(onPressed: () async {
  182. await controllers.service.serviceModeSwitch(false);
  183. }, child: const Text("卸载服务")),
  184. ],
  185. ),
  186. ) : Container(),
  187. // const SizedBox(height: 20,),
  188. // Align(
  189. // alignment: Alignment.center,
  190. // child:,
  191. // )
  192. Text(kVersion)
  193. ],
  194. );
  195. })
  196. ),
  197. );
  198. }
  199. }
  200. class UserStatusWidget extends StatefulWidget {
  201. final Future<void> Function() onRefresh; // 新增的回调
  202. final bool isActive;
  203. final bool isLoading; // 新增的变量
  204. final String username;
  205. final String userTraffic;
  206. final String expiryDate;
  207. const UserStatusWidget(
  208. {Key? key, required this.isActive, required this.isLoading, required this.username, required this.userTraffic, required this.expiryDate, required this.onRefresh})
  209. : super(key: key);
  210. @override
  211. _UserStatusWidgetState createState() => _UserStatusWidgetState();
  212. }
  213. class _UserStatusWidgetState extends State<UserStatusWidget> {
  214. @override
  215. Widget build(BuildContext context) {
  216. String imagePath = widget.isActive
  217. ? "assets/images/main/userstatus.png"
  218. : "assets/images/main/userstatusoff.png";
  219. return Align(
  220. alignment: Alignment.topCenter,
  221. child: Padding(
  222. padding: const EdgeInsets.fromLTRB(5.0, 0, 5.0, 0.0),
  223. child:
  224. Row(
  225. children: [
  226. const SizedBox(
  227. width: 80,
  228. height: 20,
  229. ),
  230. Column(
  231. crossAxisAlignment: CrossAxisAlignment.start, // 这将使子组件从左边开始对齐
  232. children: [
  233. Row(
  234. children: [
  235. Text(widget.username),
  236. const SizedBox(width: 10,),
  237. Image(
  238. image: AssetImage(imagePath),
  239. width: 80,
  240. height: 30,
  241. ),
  242. const SizedBox(width: 10,),
  243. IconButton(
  244. tooltip: '刷新账号状态',
  245. icon: widget.isLoading
  246. ? const CircularProgressIndicator()
  247. : Image.asset("assets/images/main/refresh.png"),
  248. onPressed: () {
  249. // 刷新操作
  250. if (!widget.isLoading) {
  251. widget.onRefresh();
  252. }
  253. },
  254. )
  255. ],
  256. ),
  257. Text(
  258. widget.expiryDate,
  259. style: const TextStyle(
  260. fontSize: 12.0, // 设置字体大小为20像素
  261. ),
  262. ),
  263. Text(
  264. widget.userTraffic,
  265. style: const TextStyle(
  266. fontSize: 12.0, // 设置字体大小为20像素
  267. ),
  268. )
  269. ],
  270. ),
  271. ],
  272. ),
  273. // const SizedBox(height: 10,), // 可调整间隔
  274. ),
  275. );
  276. }
  277. }