country_restricted_overlay.dart 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter/services.dart';
  3. import 'package:flutter_screenutil/flutter_screenutil.dart';
  4. import 'package:get/get.dart';
  5. import 'package:nomo/config/theme/theme_extensions/theme_extension.dart';
  6. import '../../config/translations/strings_enum.dart';
  7. import '../constants/assets.dart';
  8. import '../widgets/ix_image.dart';
  9. import '../widgets/submit_btn.dart';
  10. enum RestrictedType {
  11. region, // 地区限制
  12. user, // 用户禁用
  13. device, // 设备限制
  14. network, // 网络限制
  15. }
  16. class CountryRestrictedOverlay extends StatelessWidget {
  17. final RestrictedType type;
  18. final VoidCallback? onPressed;
  19. const CountryRestrictedOverlay({
  20. super.key,
  21. this.type = RestrictedType.region,
  22. this.onPressed,
  23. });
  24. String get _title {
  25. switch (type) {
  26. case RestrictedType.network:
  27. return "Oops!";
  28. default:
  29. return "Sorry";
  30. }
  31. }
  32. String get _content {
  33. switch (type) {
  34. case RestrictedType.network:
  35. return "Something went wrong\nUnable to load data";
  36. default:
  37. return "Due to local laws and regulations, \nNOMOVPN services are not available in \nyour current region.";
  38. }
  39. }
  40. String get _iconAsset {
  41. switch (type) {
  42. case RestrictedType.network:
  43. return Assets.oops;
  44. default:
  45. return Assets.restricted;
  46. }
  47. }
  48. @override
  49. Widget build(BuildContext context) {
  50. return WillPopScope(
  51. onWillPop: () async => false, // 禁止返回
  52. child: Scaffold(
  53. backgroundColor: Get.reactiveTheme.dialogTheme.backgroundColor,
  54. body: SafeArea(
  55. child: Stack(
  56. alignment: Alignment.center,
  57. children: [
  58. Padding(
  59. padding: EdgeInsets.all(20.w),
  60. child: SizedBox(
  61. width: double.maxFinite,
  62. child: Column(
  63. mainAxisAlignment: MainAxisAlignment.center,
  64. crossAxisAlignment: CrossAxisAlignment.center,
  65. children: [
  66. IXImage(
  67. source: _iconAsset,
  68. width: 200.w,
  69. height: 200.w,
  70. sourceType: ImageSourceType.asset,
  71. ),
  72. 30.verticalSpaceFromWidth,
  73. Text(
  74. _title,
  75. textAlign: TextAlign.center,
  76. style: TextStyle(
  77. fontSize: 24.sp,
  78. height: 1.4,
  79. fontWeight: FontWeight.w600,
  80. color: Get.reactiveTheme.primaryColor,
  81. ),
  82. ),
  83. 12.verticalSpaceFromWidth,
  84. Text(
  85. _content,
  86. textAlign: TextAlign.center,
  87. style: TextStyle(
  88. fontSize: 14.sp,
  89. height: 1.6,
  90. color: Get.reactiveTheme.hintColor,
  91. ),
  92. ),
  93. 40.verticalSpaceFromWidth,
  94. ],
  95. ),
  96. ),
  97. ),
  98. type == RestrictedType.network
  99. ? Positioned(
  100. bottom: 6.w,
  101. left: 20.w,
  102. right: 20.w,
  103. child: SubmitSvgButton(
  104. onPressed: onPressed ?? () => SystemNavigator.pop(),
  105. text: type == RestrictedType.network
  106. ? Strings.refresh.tr
  107. : Strings.exit.tr,
  108. svgPath: Assets.refersh,
  109. svgColor: Get.reactiveTheme.textTheme.bodyLarge!.color,
  110. bgColor: Get.reactiveTheme.cardColor,
  111. textColor: Get.reactiveTheme.textTheme.bodyLarge!.color,
  112. borderColor: Get.reactiveTheme.cardColor,
  113. ),
  114. )
  115. : const SizedBox.shrink(),
  116. ],
  117. ),
  118. ),
  119. ),
  120. );
  121. }
  122. }