home_view.dart 11 KB

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