home_view.dart 9.4 KB

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