home_view.dart 8.6 KB

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