Kaynağa Gözat

fix: 修改样式,适配浅色模式

lilu 1 ay önce
ebeveyn
işleme
3283031f37
69 değiştirilmiş dosya ile 468 ekleme ve 210 silme
  1. 1 3
      android/app/src/main/kotlin/app/xixi/nomo/XRayService.kt
  2. BIN
      assets/images/banner_test.png
  3. BIN
      assets/images/dark/free.png
  4. BIN
      assets/images/dark/oops.png
  5. BIN
      assets/images/dark/premium.png
  6. BIN
      assets/images/dark/premium_expired.png
  7. 0 0
      assets/images/dark/restricted.png
  8. 0 0
      assets/images/dark/subscription_wallet.png
  9. BIN
      assets/images/dark/test.png
  10. BIN
      assets/images/free.png
  11. BIN
      assets/images/identity/free.png
  12. BIN
      assets/images/identity/premium.png
  13. BIN
      assets/images/identity/test.png
  14. BIN
      assets/images/light/free.png
  15. BIN
      assets/images/light/oops.png
  16. BIN
      assets/images/light/premium.png
  17. BIN
      assets/images/light/premium_expired.png
  18. BIN
      assets/images/light/restricted.png
  19. BIN
      assets/images/light/subscription_wallet.png
  20. BIN
      assets/images/light/test.png
  21. BIN
      assets/images/oops.png
  22. BIN
      assets/images/premium.png
  23. BIN
      assets/images/premium_expired.png
  24. BIN
      assets/images/round/connected_switch.png
  25. BIN
      assets/images/round/dark_connecting.png
  26. BIN
      assets/images/round/dark_disconnecting.png
  27. BIN
      assets/images/round/disconnected_switch.png
  28. BIN
      assets/images/test.png
  29. 1 1
      assets/md/privacy.md
  30. 1 1
      assets/md/terms.md
  31. 1 2
      lib/app/base/base_view.dart
  32. 2 2
      lib/app/constants/api_domains.dart
  33. 43 19
      lib/app/constants/assets.dart
  34. 40 30
      lib/app/controllers/api_controller.dart
  35. 5 0
      lib/app/controllers/core_controller.dart
  36. 54 4
      lib/app/dialog/all_dialog.dart
  37. 7 3
      lib/app/modules/account/views/account_view.dart
  38. 1 1
      lib/app/modules/home/controllers/home_controller.dart
  39. 57 86
      lib/app/modules/home/views/home_view.dart
  40. 2 1
      lib/app/modules/home/widgets/connection_theme_button.dart
  41. 4 2
      lib/app/modules/setting/views/setting_view.dart
  42. 1 2
      lib/app/modules/splash/controllers/splash_controller.dart
  43. 3 0
      lib/app/modules/splash/views/splash_view.dart
  44. 66 23
      lib/app/modules/subscription/controllers/subscription_controller.dart
  45. 46 20
      lib/app/modules/subscription/views/subscription_view.dart
  46. 7 6
      lib/app/widgets/info_card.dart
  47. 7 3
      lib/config/theme/dark_theme_colors.dart
  48. 8 0
      lib/config/theme/light_theme_colors.dart
  49. 5 0
      lib/config/translations/ar_AR/ar_ar_translation.dart
  50. 5 0
      lib/config/translations/de_DE/de_de_translation.dart
  51. 5 0
      lib/config/translations/en_US/en_us_translation.dart
  52. 5 0
      lib/config/translations/es_ES/es_es_translation.dart
  53. 5 0
      lib/config/translations/fa_IR/fa_ir_translation.dart
  54. 5 0
      lib/config/translations/fr_FR/fr_fr_translation.dart
  55. 5 0
      lib/config/translations/hi_IN/hi_in_translation.dart
  56. 5 0
      lib/config/translations/id_ID/id_id_translation.dart
  57. 5 0
      lib/config/translations/ja_JP/ja_jp_translation.dart
  58. 5 0
      lib/config/translations/ko_KR/ko_kr_translation.dart
  59. 5 0
      lib/config/translations/my_MM/my_mm_translation.dart
  60. 5 0
      lib/config/translations/pt_BR/pt_br_translation.dart
  61. 5 0
      lib/config/translations/ru_RU/ru_ru_translation.dart
  62. 14 0
      lib/config/translations/strings_enum.dart
  63. 5 0
      lib/config/translations/th_TH/th_th_translation.dart
  64. 5 0
      lib/config/translations/tk_TM/tk_tm_translation.dart
  65. 5 0
      lib/config/translations/tl_PH/tl_ph_translation.dart
  66. 5 0
      lib/config/translations/tr_TR/tr_tr_translation.dart
  67. 5 0
      lib/config/translations/vi_VN/vi_vn_translation.dart
  68. 5 0
      lib/config/translations/zh_TW/zh_tw_translation.dart
  69. 2 1
      pubspec.yaml

+ 1 - 3
android/app/src/main/kotlin/app/xixi/nomo/XRayService.kt

@@ -79,9 +79,6 @@ class XRayService : LifecycleVpnService() {
         private const val TUN_MTU = 1500
         private const val DNS_SERVER = "8.8.8.8"
         private const val VPN_SESSION_NAME = "ix_vpn"
-
-        // 超时常量
-        private const val STOP_TUNNEL_TIMEOUT_MS = 3000L
     }
 
     override fun onCreate() {
@@ -111,6 +108,7 @@ class XRayService : LifecycleVpnService() {
         if (!logDir.exists()) {
             logDir.mkdirs()
         }
+        VLog.i(TAG, logDir.absolutePath)
         return logDir.absolutePath
     }
 

BIN
assets/images/banner_test.png


BIN
assets/images/dark/free.png


BIN
assets/images/dark/oops.png


BIN
assets/images/dark/premium.png


BIN
assets/images/dark/premium_expired.png


+ 0 - 0
assets/images/restricted.png → assets/images/dark/restricted.png


+ 0 - 0
assets/images/subscription_wallet.png → assets/images/dark/subscription_wallet.png


BIN
assets/images/dark/test.png


BIN
assets/images/free.png


BIN
assets/images/identity/free.png


BIN
assets/images/identity/premium.png


BIN
assets/images/identity/test.png


BIN
assets/images/light/free.png


BIN
assets/images/light/oops.png


BIN
assets/images/light/premium.png


BIN
assets/images/light/premium_expired.png


BIN
assets/images/light/restricted.png


BIN
assets/images/light/subscription_wallet.png


BIN
assets/images/light/test.png


BIN
assets/images/oops.png


BIN
assets/images/premium.png


BIN
assets/images/premium_expired.png


BIN
assets/images/round/connected_switch.png


BIN
assets/images/round/dark_connecting.png


BIN
assets/images/round/dark_disconnecting.png


BIN
assets/images/round/disconnected_switch.png


BIN
assets/images/test.png


+ 1 - 1
assets/md/privacy.md

@@ -1,6 +1,6 @@
 # Privacy Policy
 
-Last updated on: [Insert Date]
+Last updated on: 2026-01-28
 
 ## Introduction
 

+ 1 - 1
assets/md/terms.md

@@ -1,6 +1,6 @@
 # Terms of Use Agreement
 
-Last updated on: [Insert Date]
+Last updated on: 2026-01-28
 
 By using the services provided by NOMO VPN ("Service"), you agree to be bound by the terms and conditions hereinafter set forth. This Agreement shall take effect upon your download, installation, or use of NOMO VPN. If you do not agree to any of the following terms, you must immediately uninstall and cease using NOMO VPN.
 

+ 1 - 2
lib/app/base/base_view.dart

@@ -43,8 +43,7 @@ abstract class BaseView<T> extends GetView<T> {
         backgroundColor: Get.reactiveTheme.scaffoldBackgroundColor,
         appBar: appBar,
         extendBody: extendBody,
-        //extendBodyBehindAppBar: extendBodyBehindAppBar,
-        extendBodyBehindAppBar: false,
+        extendBodyBehindAppBar: extendBodyBehindAppBar,
         bottomNavigationBar: bottomNavigationBar,
         floatingActionButton: floatingActionButton,
         floatingActionButtonLocation: floatingActionButtonLocation,

+ 2 - 2
lib/app/constants/api_domains.dart

@@ -133,8 +133,8 @@ class ApiDomains {
   void initUrls() {
     if (Configs.debug) {
       _apiUrls = [
-        // 'https://api.znomo.com', // 测试环境
-        "https://nomo-api.clickto.dev", // 开发环境
+        'https://api.znomo.com', // 测试环境
+        // "https://nomo-api.clickto.dev", // 开发环境
       ];
       _routerUrls = [];
       _logUrls = [];

+ 43 - 19
lib/app/constants/assets.dart

@@ -1,3 +1,5 @@
+import 'package:nomo/config/theme/theme_extensions/theme_extension.dart';
+
 class Assets {
   // 国旗
   static String getCountryFlagImage(String contryCode) {
@@ -50,8 +52,16 @@ class Assets {
   static const String refersh = 'assets/vectors/boost/refersh.svg';
 
   // 错误页
-  static const String restricted = 'assets/images/restricted.png';
-  static const String oops = 'assets/images/oops.png';
+  static const String _restrictedDark = 'assets/images/dark/restricted.png';
+  static const String _oopsDark = 'assets/images/dark/oops.png';
+
+  static const String _restrictedLight = 'assets/images/light/restricted.png';
+  static const String _oopsLight = 'assets/images/light/oops.png';
+
+  // 根据主题获取标签资源
+  static String get restricted =>
+      ReactiveTheme.isLightTheme ? _restrictedLight : _restrictedDark;
+  static String get oops => ReactiveTheme.isLightTheme ? _oopsLight : _oopsDark;
 
   // 连接状态
   static const String disconnected = 'assets/images/disconnected.png';
@@ -60,10 +70,27 @@ class Assets {
   static const String connectingError = 'assets/images/vpn_error.png';
   static const String connectionNetworkError = 'assets/images/network.png';
 
-  static const String premium = 'assets/images/premium.png';
-  static const String premiumExpired = 'assets/images/premium_expired.png';
-  static const String test = 'assets/images/test.png';
-  static const String free = 'assets/images/free.png';
+  // 标签资源 - Dark 版本
+  static const String _premiumDark = 'assets/images/dark/premium.png';
+  static const String _premiumExpiredDark =
+      'assets/images/dark/premium_expired.png';
+  static const String _testDark = 'assets/images/dark/test.png';
+  static const String _freeDark = 'assets/images/dark/free.png';
+
+  // 标签资源 - Light 版本
+  static const String _premiumLight = 'assets/images/light/premium.png';
+  static const String _premiumExpiredLight =
+      'assets/images/light/premium_expired.png';
+  static const String _testLight = 'assets/images/light/test.png';
+  static const String _freeLight = 'assets/images/light/free.png';
+
+  // 根据主题获取标签资源
+  static String get premium =>
+      ReactiveTheme.isLightTheme ? _premiumLight : _premiumDark;
+  static String get premiumExpired =>
+      ReactiveTheme.isLightTheme ? _premiumExpiredLight : _premiumExpiredDark;
+  static String get test => ReactiveTheme.isLightTheme ? _testLight : _testDark;
+  static String get free => ReactiveTheme.isLightTheme ? _freeLight : _freeDark;
 
   // 评价
   static const String poutingFace = 'assets/vectors/boost/pouting_face.svg';
@@ -76,8 +103,14 @@ class Assets {
   // 订阅
   static const String subscriptionDiamond =
       'assets/images/subscription_diamond.png';
-  static const String subscriptionWallet =
-      'assets/images/subscription_wallet.png';
+  static const String _subscriptionWalletDark =
+      'assets/images/dark/subscription_wallet.png';
+  static const String _subscriptionWalletLight =
+      'assets/images/light/subscription_wallet.png';
+  static String get subscriptionWallet => ReactiveTheme.isLightTheme
+      ? _subscriptionWalletLight
+      : _subscriptionWalletDark;
+
   static const String subscriptionGreenShield =
       'assets/images/subscription_green_shield.png';
 
@@ -109,12 +142,6 @@ class Assets {
       'assets/vectors/push_notifications.svg';
   static const String update = 'assets/vectors/update.svg';
 
-  // 圆形连接按钮资源
-  static const String connectedSwitch =
-      'assets/images/round/connected_switch.png';
-  static const String disconnectedSwitch =
-      'assets/images/round/disconnected_switch.png';
-
   // 连接按钮中间的图片
   static const String darkDisconnected =
       'assets/images/round/dark_disconnected.png';
@@ -127,14 +154,11 @@ class Assets {
       'assets/images/round/dark_connecting.png';
   static const String lightConnecting =
       'assets/images/round/light_connecting.png';
+  static const String darkDisconnecting =
+      'assets/images/round/dark_disconnecting.png';
 
   static const String settingsTheme = 'assets/vectors/settings_theme.svg';
 
-  // home页的会员
-  static const String homePremium = 'assets/images/identity/premium.png';
-  static const String homeTest = 'assets/images/identity/test.png';
-  static const String homeFree = 'assets/images/identity/free.png';
-
   // windows 托盘图标
   static const String trayIconDarkConnectedWin =
       'assets/trayicon/dark/connected.ico';

+ 40 - 30
lib/app/controllers/api_controller.dart

@@ -1113,9 +1113,16 @@ class ApiController extends GetxService with WidgetsBindingObserver {
       };
 
       // 上传日志
-      await uploadMetricsLog([logItem]);
-      await uploadLocalLog(appLog['sessionInfo']?['boostSessionId'] ?? '');
-      log(TAG, 'Boost log uploaded successfully');
+      try {
+        await uploadMetricsLog([logItem]);
+      } catch (e) {
+        log(TAG, 'uploadMetricsLog error: $e');
+      }
+      try {
+        await uploadLocalLog(appLog['sessionInfo']?['boostSessionId'] ?? '');
+      } catch (e) {
+        log(TAG, 'uploadLocalLog error: $e');
+      }
     } catch (e) {
       log(TAG, 'uploadBoostLog error: $e');
     }
@@ -1133,9 +1140,9 @@ class ApiController extends GetxService with WidgetsBindingObserver {
     try {
       final appDir = await getApplicationSupportDirectory();
       final logDir = Directory('${appDir.path}/logs');
+      final xrayDir = Directory('${appDir.path}/xray');
+      final filePaths = <String>[];
       if (await logDir.exists()) {
-        final filePaths = <String>[];
-
         // 遍历 logDir 目录,查找 client_ 和 service_ 开头的文件
         await for (final entity in logDir.list()) {
           if (entity is File) {
@@ -1146,25 +1153,27 @@ class ApiController extends GetxService with WidgetsBindingObserver {
             }
           }
         }
-
-        if (filePaths.isEmpty) {
-          log(TAG, 'No client_ or service_ log files found');
-          return;
-        }
-
-        final gzipFilePath = await GzipManager().generateAndShareGzip(
-          filePaths: filePaths,
-          gzipFileName: '$boostSessionId.tar.gz',
-        );
-        if (gzipFilePath == null) {
-          return;
+      }
+      if (await xrayDir.exists()) {
+        // 遍历 logDir 目录,查找 client_ 和 service_ 开头的文件
+        await for (final entity in xrayDir.list()) {
+          if (entity is File) {
+            filePaths.add(entity.path);
+          }
         }
-        await uploadLogFile(
-          gzipFilePath,
-          boostSessionId,
-          LogModule.NM_Log.name,
-        );
       }
+      if (filePaths.isEmpty) {
+        log(TAG, 'No client_ or service_ log files found');
+        return;
+      }
+      final gzipFilePath = await GzipManager().generateAndShareGzip(
+        filePaths: filePaths,
+        gzipFileName: '$boostSessionId.tar.gz',
+      );
+      if (gzipFilePath == null) {
+        return;
+      }
+      await uploadLogFile(gzipFilePath, boostSessionId, LogModule.NM_Log.name);
     } catch (e) {
       rethrow;
     }
@@ -1545,12 +1554,13 @@ class ApiController extends GetxService with WidgetsBindingObserver {
 
   /// 获取有效期显示文本
   String _getValidTermText() {
-    final subscribeType = _getSubscribeTypeText();
+    // final subscribeType = _getSubscribeTypeText();
     final expireTime = _getExpireTimeText();
 
-    if (subscribeType.isNotEmpty && expireTime.isNotEmpty) {
-      return '$subscribeType / $expireTime';
-    } else if (expireTime.isNotEmpty) {
+    // if (subscribeType.isNotEmpty && expireTime.isNotEmpty) {
+    //   return '$subscribeType / $expireTime';
+    // }
+    if (expireTime.isNotEmpty) {
       return expireTime;
     }
     return '';
@@ -1629,7 +1639,7 @@ class ApiController extends GetxService with WidgetsBindingObserver {
   /// 格式化剩余时间显示
   String _formatRemainTime(int totalSeconds) {
     if (totalSeconds <= 0) {
-      return '--';
+      return Strings.expired.tr;
     }
 
     final days = totalSeconds ~/ 86400;
@@ -1639,15 +1649,15 @@ class ApiController extends GetxService with WidgetsBindingObserver {
 
     // 大于1天
     if (days > 1) {
-      return '$days days';
+      return '$days ${Strings.days.tr}';
     }
     // 等于1天
     if (days == 1) {
-      return '1 day';
+      return '1 ${Strings.day.tr}';
     }
     // 大于1小时
     if (hours >= 1) {
-      return '$hours h';
+      return '$hours ${Strings.hour.tr}';
     }
     // 小于1小时,显示 mm:ss
     return '${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';

+ 5 - 0
lib/app/controllers/core_controller.dart

@@ -7,6 +7,7 @@ import 'package:dio/dio.dart';
 import 'package:get/get.dart';
 import 'package:nomo/app/constants/api_domains.dart';
 import 'package:nomo/app/constants/keys.dart';
+import 'package:nomo/app/dialog/all_dialog.dart';
 import 'package:package_info_plus/package_info_plus.dart';
 import 'package:uuid/uuid.dart';
 
@@ -556,6 +557,10 @@ class CoreController extends GetxService {
         errorMessage = Strings.remainTimeEnded.tr;
         break;
     }
+    if (code == Errors.ERROR_REMAIN_TIME) {
+      AllDialog.showMembershipExpired();
+      return;
+    }
     if (errorMessage.isNotEmpty) {
       ErrorDialog.show(message: errorMessage);
     }

+ 54 - 4
lib/app/dialog/all_dialog.dart

@@ -16,19 +16,19 @@ class AllDialog {
   static void showBindEmailMemberBenefits() {
     final isLight = ReactiveTheme.isLightTheme;
     CustomDialog.showError(
-      title: Strings.bindEmailMemberBenefits.tr,
-      message: Strings.bindingAccountEmailProtectsPreRights.tr,
+      title: Strings.associatedInterests.tr,
+      message: Strings.associatedInterestsDesc.tr,
       icon: IconFont.icon23,
       iconColor: isLight
           ? Get.reactiveTheme.primaryColor
           : DarkThemeColors.subscriptionColor,
       titleColor: isLight ? Get.reactiveTheme.primaryColor : null,
-      buttonText: Strings.login.tr,
+      buttonText: Strings.signup.tr,
       cancelText: Strings.cancel.tr,
       onPressed: () {
         // 处理重试逻辑
         Navigator.of(Get.context!).pop();
-        Get.toNamed(Routes.LOGIN);
+        Get.toNamed(Routes.SIGNUP);
       },
       onCancel: () {
         // 处理取消逻辑
@@ -213,6 +213,56 @@ class AllDialog {
     );
   }
 
+  /// 显示会员过期弹窗
+  static void showMembershipExpired() {
+    final isLight = ReactiveTheme.isLightTheme;
+    CustomDialog.showError(
+      title: Strings.membershipExpired.tr,
+      message: Strings.membershipExpiredMessage.tr,
+      icon: IconFont.icon23,
+      iconColor: isLight
+          ? Get.reactiveTheme.primaryColor
+          : DarkThemeColors.subscriptionColor,
+      titleColor: isLight ? Get.reactiveTheme.primaryColor : null,
+      buttonText: Strings.subscribeNow.tr,
+      cancelText: Strings.cancel.tr,
+      onPressed: () {
+        // 处理重试逻辑
+        Navigator.of(Get.context!).pop();
+        Get.toNamed(Routes.SUBSCRIPTION);
+      },
+      onCancel: () {
+        // 处理取消逻辑
+        Navigator.of(Get.context!).pop();
+      },
+    );
+  }
+
+  /// 显示订阅网页弹窗
+  static void showSubscriptionForWeb(Function() onRefresh) {
+    final isLight = ReactiveTheme.isLightTheme;
+    CustomDialog.showError(
+      title: Strings.subscriptionForWebTitle.tr,
+      message: Strings.subscriptionForWebMessage.tr,
+      icon: IconFont.icon23,
+      iconColor: isLight
+          ? Get.reactiveTheme.primaryColor
+          : DarkThemeColors.subscriptionColor,
+      titleColor: isLight ? Get.reactiveTheme.primaryColor : null,
+      buttonText: Strings.ok.tr,
+      cancelText: Strings.cancel.tr,
+      onPressed: () {
+        // 处理重试逻辑
+        Navigator.of(Get.context!).pop();
+        onRefresh();
+      },
+      onCancel: () {
+        // 处理取消逻辑
+        Navigator.of(Get.context!).pop();
+      },
+    );
+  }
+
   /// 显示自定义成功弹窗
   static void showCustomSuccess({
     required String title,

+ 7 - 3
lib/app/modules/account/views/account_view.dart

@@ -489,7 +489,9 @@ class AccountView extends BaseView<AccountController> {
                       : Strings.expired.tr,
                   style: TextStyle(
                     fontSize: 13.sp,
-                    color: Get.reactiveTheme.primaryColor,
+                    color: controller.apiController.remainTimeSeconds > 0
+                        ? Get.reactiveTheme.primaryColor
+                        : Colors.red,
                     fontWeight: FontWeight.w500,
                   ),
                 ),
@@ -503,10 +505,12 @@ class AccountView extends BaseView<AccountController> {
                 iconColor: Get.reactiveTheme.shadowColor,
                 title: Strings.freeTime.tr,
                 trailing: Text(
-                  '${controller.apiController.remainTimeFormatted} / Days',
+                  controller.apiController.remainTimeFormatted,
                   style: TextStyle(
                     fontSize: 14.sp,
-                    color: const Color(0xFFFFCC00),
+                    color: controller.apiController.remainTimeSeconds > 0
+                        ? Get.reactiveTheme.primaryColor
+                        : Colors.red,
                     fontWeight: FontWeight.w500,
                   ),
                 ),

+ 1 - 1
lib/app/modules/home/controllers/home_controller.dart

@@ -300,7 +300,7 @@ class HomeController extends BaseController {
 
       // 请求最新数据
       final banners = await apiController.getBanner(position: position);
-      if (banners.list != null && banners.list!.isNotEmpty) {
+      if (banners.list != null) {
         if (position == 'banner') {
           bannerList = banners.list!;
         } else if (position == 'nine') {

+ 57 - 86
lib/app/modules/home/views/home_view.dart

@@ -9,6 +9,7 @@ import 'package:nomo/app/extensions/widget_extension.dart';
 import 'package:nomo/utils/misc.dart';
 import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
 import '../../../../config/theme/dark_theme_colors.dart';
+import '../../../../config/theme/light_theme_colors.dart';
 import '../../../../config/theme/theme_extensions/theme_extension.dart';
 import '../../../../config/translations/strings_enum.dart';
 import '../../../base/base_view.dart';
@@ -205,7 +206,8 @@ class HomeView extends BaseView<HomeController> {
                                     }),
                                   ),
                                   MenuList(),
-                                  14.verticalSpaceFromWidth,
+                                  if (controller.nineBannerList.isNotEmpty)
+                                    14.verticalSpaceFromWidth,
                                 ],
                               ),
                             ),
@@ -229,89 +231,51 @@ class HomeView extends BaseView<HomeController> {
       children: [
         Obx(() {
           final bgColor = controller.apiController.userLevel == 3
-              ? DarkThemeColors.homePremiumColor
+              ? ReactiveTheme.isLightTheme
+                    ? LightThemeColors.homePremiumColor
+                    : DarkThemeColors.homePremiumColor
               : controller.apiController.userLevel == 9999
-              ? DarkThemeColors.homeTestColor
+              ? ReactiveTheme.isLightTheme
+                    ? LightThemeColors.homeTestColor
+                    : DarkThemeColors.homeTestColor
+              : ReactiveTheme.isLightTheme
+              ? LightThemeColors.homeFreeColor
               : DarkThemeColors.homeFreeColor;
-          return ClipRRect(
-            borderRadius: BorderRadius.circular(100.r),
-            child: ClickOpacity(
-              onTap: () => Get.toNamed(Routes.SUBSCRIPTION),
-              child: Container(
-                decoration: BoxDecoration(
-                  color: bgColor.withValues(alpha: 0.05),
-                ),
-                child: Stack(
-                  children: [
-                    // 左上角光晕
-                    Positioned(
-                      left: -8.w,
-                      top: -16.w,
-                      child: Container(
-                        width: 32.w,
-                        height: 32.w,
-                        decoration: BoxDecoration(
-                          shape: BoxShape.circle,
-                          gradient: RadialGradient(
-                            colors: [
-                              bgColor.withValues(alpha: 0.85),
-                              bgColor.withValues(alpha: 0.05),
-                            ],
-                            stops: const [0.0, 1.0],
-                          ),
-                        ),
-                      ),
-                    ),
-                    // 右下角光晕
-                    Positioned(
-                      right: 12.w,
-                      bottom: -12.w,
-                      child: ImageFiltered(
-                        imageFilter: ImageFilter.blur(
-                          sigmaX: 8,
-                          sigmaY: 8,
-                          tileMode: TileMode.decal,
-                        ),
-                        child: Container(
-                          width: 42.w,
-                          height: 16.w,
-                          decoration: BoxDecoration(
-                            borderRadius: BorderRadius.circular(8.w),
-                            color: bgColor.withValues(alpha: 0.85),
-                          ),
-                        ),
-                      ),
-                    ),
-                    Padding(
-                      padding: EdgeInsets.symmetric(
-                        horizontal: 6.w,
-                        vertical: 4.w,
-                      ),
-                      child: Row(
-                        children: [
-                          Obx(
-                            () => IXImage(
-                              source: controller.apiController.userLevel == 3
-                                  ? Assets.homePremium
-                                  : controller.apiController.userLevel == 9999
-                                  ? Assets.homeTest
-                                  : Assets.homeFree,
-                              width: controller.apiController.userLevel == 3
-                                  ? 92.w
-                                  : 64.w,
-                              height: 28.w,
-                              sourceType: ImageSourceType.asset,
-                            ),
-                          ),
-                          _buildReminder(),
-                        ],
-                      ),
-                    ),
 
-                    // 倒计时提醒
-                  ],
+          return ClickOpacity(
+            onTap: () => Get.toNamed(Routes.SUBSCRIPTION),
+            child: Stack(
+              children: [
+                Container(
+                  height: 28.w,
+                  padding: EdgeInsets.only(left: 32.w, right: 8.w),
+                  alignment: Alignment.center,
+                  margin: controller.apiController.userLevel == 3
+                      ? EdgeInsets.only(left: 64.w)
+                      : EdgeInsets.only(left: 36.w),
+                  decoration: BoxDecoration(
+                    borderRadius: BorderRadius.circular(100.r),
+                    color: bgColor,
+                  ),
+                  child: _buildReminder(),
                 ),
-              ),
+                Obx(
+                  () => IXImage(
+                    source: controller.apiController.userLevel == 3
+                        ? controller.apiController.remainTimeSeconds > 0
+                              ? Assets.premium
+                              : Assets.premiumExpired
+                        : controller.apiController.userLevel == 9999
+                        ? Assets.test
+                        : Assets.free,
+                    width: controller.apiController.userLevel == 3
+                        ? 92.w
+                        : 64.w,
+                    height: 28.w,
+                    sourceType: ImageSourceType.asset,
+                  ),
+                ),
+              ],
             ),
           );
         }),
@@ -368,19 +332,26 @@ class HomeView extends BaseView<HomeController> {
       if (!controller.apiController.shouldShowCountdown) {
         return const SizedBox.shrink();
       }
+      final textColor = controller.apiController.userLevel == 3
+          ? ReactiveTheme.isLightTheme
+                ? LightThemeColors.homePremiumTextColor
+                : DarkThemeColors.homePremiumTextColor
+          : controller.apiController.userLevel == 9999
+          ? ReactiveTheme.isLightTheme
+                ? LightThemeColors.homeTestTextColor
+                : DarkThemeColors.homeTestTextColor
+          : ReactiveTheme.isLightTheme
+          ? LightThemeColors.homeFreeTextColor
+          : DarkThemeColors.homeFreeTextColor;
       return Text(
-        '${controller.apiController.remainTimeFormatted} ',
+        controller.apiController.remainTimeFormatted,
         style: TextStyle(
           fontSize: 13.sp,
           height: 1.5,
           fontStyle: FontStyle.italic,
           fontWeight: FontWeight.w500,
           fontFeatures: [FontFeature.tabularFigures()],
-          color:
-              controller.apiController.userLevel == 3 ||
-                  controller.apiController.userLevel == 9999
-              ? Get.reactiveTheme.textTheme.bodyLarge!.color
-              : Get.reactiveTheme.hintColor,
+          color: textColor,
         ),
       );
     });

+ 2 - 1
lib/app/modules/home/widgets/connection_theme_button.dart

@@ -346,8 +346,9 @@ class _ConnectionThemeButtonState extends State<ConnectionThemeButton>
         return isDark ? Assets.darkDisconnected : Assets.lightDisconnected;
       case ConnectionState.connectingVirtual:
       case ConnectionState.connecting:
+        return isDark ? Assets.darkConnecting : Assets.lightConnecting;
       case ConnectionState.disconnecting:
-        return isDark ? Assets.darkDisconnected : Assets.lightDisconnected;
+        return Assets.darkDisconnecting;
       case ConnectionState.connected:
         // 连接成功时使用白色图标(因为背景是蓝色渐变)
         return Assets.darkConnected;

+ 4 - 2
lib/app/modules/setting/views/setting_view.dart

@@ -245,10 +245,12 @@ class SettingView extends BaseView<SettingController> {
                   iconColor: Get.reactiveTheme.shadowColor,
                   title: Strings.freeTime.tr,
                   trailing: Text(
-                    '${controller.apiController.remainTimeFormatted} / Days',
+                    controller.apiController.remainTimeFormatted,
                     style: TextStyle(
                       fontSize: 14.sp,
-                      color: const Color(0xFFFFCC00),
+                      color: controller.apiController.remainTimeSeconds > 0
+                          ? Get.reactiveTheme.primaryColor
+                          : Colors.red,
                       fontWeight: FontWeight.w500,
                     ),
                   ),

+ 1 - 2
lib/app/modules/splash/controllers/splash_controller.dart

@@ -97,8 +97,7 @@ class SplashController extends BaseController {
           if (appConfig.visitorDisabled ?? true) {
             // 延迟1秒后设置为未登录
             Future.delayed(const Duration(seconds: 1), () {
-              // hasLogin = false;
-              Get.offAllNamed(Routes.HOME);
+              hasLogin = false;
             });
           } else {
             //允许游客访问,直接进入主页

+ 3 - 0
lib/app/modules/splash/views/splash_view.dart

@@ -146,6 +146,9 @@ class SplashView extends BaseView<SplashController> {
                       SubmitButton(
                         text: Strings.loginButton.tr,
                         bgColor: Get.reactiveTheme.highlightColor,
+                        textColor: ReactiveTheme.isLightTheme
+                            ? Get.reactiveTheme.primaryColor
+                            : null,
                         onPressed: () => Get.toNamed(Routes.LOGIN),
                       ),
                       20.verticalSpaceFromWidth,

+ 66 - 23
lib/app/modules/subscription/controllers/subscription_controller.dart

@@ -1,19 +1,23 @@
 import 'dart:async';
 
 import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
 import 'package:get/get.dart';
 import 'package:in_app_purchase/in_app_purchase.dart';
+import 'package:nomo/config/theme/theme_extensions/theme_extension.dart';
 import 'package:video_player/video_player.dart';
 
 import '../../../../config/theme/dark_theme_colors.dart';
 import '../../../../config/translations/strings_enum.dart';
 import '../../../../utils/in_app_purchase_util.dart';
 import '../../../../utils/log/logger.dart';
+import '../../../../utils/system_helper.dart';
 import '../../../components/ix_snackbar.dart';
 import '../../../constants/assets.dart';
 import '../../../controllers/api_controller.dart';
 import '../../../data/models/channelplan/channel_plan_list.dart';
 import '../../../data/sp/ix_sp.dart';
+import '../../../dialog/all_dialog.dart';
 import '../../../dialog/loading/loading_dialog.dart';
 
 class SubscriptionController extends GetxController {
@@ -98,8 +102,7 @@ class SubscriptionController extends GetxController {
   Color? _getBadgeBgColor(ChannelPlan plan) {
     if (plan.tagType == 1) {
       return DarkThemeColors.bg1;
-    }
-    if (plan.tag != null && plan.tag!.isNotEmpty) {
+    } else if (plan.tagType == 2) {
       return DarkThemeColors.primaryColor;
     }
     return null;
@@ -109,13 +112,23 @@ class SubscriptionController extends GetxController {
   Color? _getBadgeTextColor(ChannelPlan plan) {
     if (plan.tagType == 1) {
       return DarkThemeColors.subscriptionColor;
-    }
-    if (plan.tag != null && plan.tag!.isNotEmpty) {
+    } else if (plan.tagType == 2) {
       return Colors.white;
     }
     return null;
   }
 
+  Color? _getBadgeBorderColor(ChannelPlan plan) {
+    if (plan.tagType == 1) {
+      return ReactiveTheme.isLightTheme
+          ? DarkThemeColors.subscriptionColor
+          : DarkThemeColors.dividerColor;
+    } else if (plan.tagType == 2) {
+      return null;
+    }
+    return null;
+  }
+
   @override
   void onInit() {
     super.onInit();
@@ -123,11 +136,37 @@ class SubscriptionController extends GetxController {
     // _initializeInAppPurchase();
     _getChannelPlanList();
     refreshSubscriptionStatus();
+    // 设置状态栏颜色
+
+    _setSystemUIOverlayStyle(ReactiveTheme.isLightTheme, true);
+  }
+
+  void _setSystemUIOverlayStyle(bool isLight, bool changeDarkMode) {
+    if (isLight) {
+      if (changeDarkMode) {
+        SystemChrome.setSystemUIOverlayStyle(
+          SystemUiOverlayStyle(
+            statusBarColor: Get.reactiveTheme.scaffoldBackgroundColor,
+            statusBarIconBrightness: Brightness.light,
+            statusBarBrightness: Brightness.light,
+          ),
+        );
+      } else {
+        SystemChrome.setSystemUIOverlayStyle(
+          SystemUiOverlayStyle(
+            statusBarColor: Get.reactiveTheme.scaffoldBackgroundColor,
+            statusBarIconBrightness: Brightness.dark,
+            statusBarBrightness: Brightness.dark,
+          ),
+        );
+      }
+    }
   }
 
   @override
   void onClose() {
     videoController.dispose();
+    _setSystemUIOverlayStyle(ReactiveTheme.isLightTheme, false);
     // 注意: 不要在这里调用 _iapUtil.dispose()
     // 因为它是单例,可能在其他地方还在使用
     super.onClose();
@@ -158,21 +197,28 @@ class SubscriptionController extends GetxController {
 
   /// 购买套餐
   Future<void> subscribe() async {
-    await LoadingDialog.show(
-      context: Get.context!,
-      loadingText: 'Purchasing...',
-      successText: 'Purchase successful',
-      onRequest: () async {
-        // 执行你的异步请求
-        await _apiController.subscribe({
-          'channelItemId': selectedPlan?.channelItemId,
-        });
-      },
-      onSuccess: () async {
-        // 刷新用户信息
-        refreshSubscriptionStatus();
-      },
-    );
+    if (selectedPlan?.payoutType == 'default') {
+      await LoadingDialog.show(
+        context: Get.context!,
+        loadingText: 'Purchasing...',
+        successText: 'Purchase successful',
+        onRequest: () async {
+          // 执行你的异步请求
+          await _apiController.subscribe({
+            'channelItemId': selectedPlan?.channelItemId,
+          });
+        },
+        onSuccess: () async {
+          // 刷新用户信息
+          refreshSubscriptionStatus();
+        },
+      );
+    } else if (selectedPlan?.payoutType == 'web') {
+      SystemHelper.openWebPage(selectedPlan?.payoutData ?? '');
+      AllDialog.showSubscriptionForWeb(() {
+        _apiController.refreshLaunch();
+      });
+    }
   }
 
   /// 初始化内购
@@ -454,10 +500,7 @@ class SubscriptionController extends GetxController {
   /// 获取指定索引的标签边框颜色
   Color? getPlanBadgeBorderColor(int index) {
     if (index < channelPlans.length) {
-      final plan = channelPlans[index];
-      if (plan.recommend == true) {
-        return DarkThemeColors.dividerColor;
-      }
+      return _getBadgeBorderColor(channelPlans[index]);
     }
     return null;
   }

+ 46 - 20
lib/app/modules/subscription/views/subscription_view.dart

@@ -5,6 +5,7 @@ import 'package:nomo/app/constants/iconfont/iconfont.dart';
 import 'package:nomo/config/theme/dark_theme_colors.dart';
 import 'package:nomo/config/theme/theme_extensions/theme_extension.dart';
 import 'package:video_player/video_player.dart';
+import '../../../../config/theme/light_theme_colors.dart';
 import '../../../../config/translations/strings_enum.dart';
 import '../../../constants/assets.dart';
 import '../../../widgets/info_card.dart';
@@ -17,7 +18,7 @@ class SubscriptionView extends GetView<SubscriptionController> {
   @override
   Widget build(BuildContext context) {
     return Scaffold(
-      backgroundColor: DarkThemeColors.scaffoldBackgroundColor,
+      backgroundColor: Get.reactiveTheme.scaffoldBackgroundColor,
       body: Stack(
         children: [
           // 视频背景层(只显示顶部214高度)
@@ -53,8 +54,12 @@ class SubscriptionView extends GetView<SubscriptionController> {
                 gradient: LinearGradient(
                   begin: Alignment.topCenter,
                   end: Alignment.bottomCenter,
-                  colors: [Colors.black.withValues(alpha: 0.6), Colors.black],
-                  stops: const [0.0, 1.0],
+                  colors: ReactiveTheme.isLightTheme
+                      ? [Colors.black, Color(0x99F5D89F), Color(0xFFEFF1F5)]
+                      : [Colors.black.withValues(alpha: 0.6), Colors.black],
+                  stops: ReactiveTheme.isLightTheme
+                      ? const [0.0, 0.7, 1.0]
+                      : const [0.0, 1.0],
                 ),
               ),
             ),
@@ -116,10 +121,18 @@ class SubscriptionView extends GetView<SubscriptionController> {
               width: 24.w,
               height: 24.w,
               decoration: BoxDecoration(
-                color: Colors.white.withValues(alpha: 0.1),
+                color: ReactiveTheme.isLightTheme
+                    ? LightThemeColors.strokes1
+                    : Color(0xFF333333),
                 shape: BoxShape.circle,
               ),
-              child: Icon(Icons.close_rounded, color: Colors.white, size: 16.w),
+              child: Icon(
+                Icons.close_rounded,
+                color: ReactiveTheme.isLightTheme
+                    ? LightThemeColors.text2
+                    : Colors.white,
+                size: 16.w,
+              ),
             ),
           ),
         ],
@@ -173,7 +186,9 @@ class SubscriptionView extends GetView<SubscriptionController> {
                       style: TextStyle(
                         fontSize: 14.sp,
                         height: 1.4,
-                        color: DarkThemeColors.subscriptionColor,
+                        color: ReactiveTheme.isLightTheme
+                            ? LightThemeColors.text1
+                            : DarkThemeColors.subscriptionColor,
                         fontWeight: FontWeight.w700,
                       ),
                     ),
@@ -185,7 +200,7 @@ class SubscriptionView extends GetView<SubscriptionController> {
                   style: TextStyle(
                     fontSize: 14.sp,
                     height: 1.4,
-                    color: Colors.white,
+                    color: Get.reactiveTheme.textTheme.bodyLarge!.color,
                   ),
                 ),
               ],
@@ -250,12 +265,12 @@ class SubscriptionView extends GetView<SubscriptionController> {
         child: Container(
           margin: EdgeInsets.only(bottom: 18.w),
           decoration: BoxDecoration(
-            color: DarkThemeColors.cardColor,
+            color: Get.reactiveTheme.cardColor,
             borderRadius: BorderRadius.circular(12.r),
             border: Border.all(
               color: isSelected
                   ? DarkThemeColors.subscriptionColor
-                  : DarkThemeColors.dividerColor,
+                  : Get.reactiveTheme.cardColor,
               width: 2.w,
             ),
           ),
@@ -278,7 +293,8 @@ class SubscriptionView extends GetView<SubscriptionController> {
                             style: TextStyle(
                               fontSize: 18.sp,
                               height: 1.4,
-                              color: DarkThemeColors.bodyTextColor,
+                              color:
+                                  Get.reactiveTheme.textTheme.bodyLarge!.color,
                               fontWeight: FontWeight.w600,
                             ),
                           ),
@@ -287,7 +303,7 @@ class SubscriptionView extends GetView<SubscriptionController> {
                             style: TextStyle(
                               fontSize: 12.sp,
                               height: 1.6,
-                              color: DarkThemeColors.hintTextColor,
+                              color: Get.reactiveTheme.hintColor,
                             ),
                           ),
                         ],
@@ -301,7 +317,7 @@ class SubscriptionView extends GetView<SubscriptionController> {
                           style: TextStyle(
                             fontSize: 13.sp,
                             height: 1.4,
-                            color: DarkThemeColors.bodyTextColor,
+                            color: Get.reactiveTheme.textTheme.bodyLarge!.color,
                           ),
                         ),
                         8.horizontalSpace,
@@ -313,6 +329,8 @@ class SubscriptionView extends GetView<SubscriptionController> {
                             border: Border.all(
                               color: isSelected
                                   ? DarkThemeColors.primaryColor
+                                  : ReactiveTheme.isLightTheme
+                                  ? LightThemeColors.strokes1
                                   : Colors.white30,
                               width: 1.5.w,
                             ),
@@ -400,7 +418,9 @@ class SubscriptionView extends GetView<SubscriptionController> {
           Strings.premiumsIncluded.tr,
           style: TextStyle(
             fontSize: 16.sp,
-            color: DarkThemeColors.subscriptionColor,
+            color: ReactiveTheme.isLightTheme
+                ? LightThemeColors.primaryColor
+                : DarkThemeColors.subscriptionColor,
             fontWeight: FontWeight.w500,
           ),
         ),
@@ -408,7 +428,7 @@ class SubscriptionView extends GetView<SubscriptionController> {
         Container(
           padding: EdgeInsets.symmetric(vertical: 4.w, horizontal: 10.w),
           decoration: BoxDecoration(
-            color: DarkThemeColors.bgDisable,
+            color: Get.reactiveTheme.cardColor,
             borderRadius: BorderRadius.circular(12.r),
           ),
           child: Column(
@@ -444,7 +464,13 @@ class SubscriptionView extends GetView<SubscriptionController> {
       height: 44.w,
       child: Row(
         children: [
-          Icon(icon, color: DarkThemeColors.subscriptionColor, size: 24.w),
+          Icon(
+            icon,
+            color: ReactiveTheme.isLightTheme
+                ? LightThemeColors.primaryColor
+                : DarkThemeColors.subscriptionColor,
+            size: 24.w,
+          ),
           12.horizontalSpace,
           Expanded(
             child: Text(
@@ -475,7 +501,7 @@ class SubscriptionView extends GetView<SubscriptionController> {
       padding: EdgeInsets.symmetric(vertical: 10.w, horizontal: 14.w),
       decoration: BoxDecoration(
         border: Border(
-          top: BorderSide(color: Colors.white.withOpacity(0.1), width: 1),
+          top: BorderSide(color: Get.reactiveTheme.dividerColor, width: 1),
         ),
       ),
       child: Column(
@@ -516,7 +542,7 @@ class SubscriptionView extends GetView<SubscriptionController> {
                   Strings.restorePurchases.tr,
                   style: TextStyle(
                     fontSize: 16.sp,
-                    color: DarkThemeColors.bodyTextColor,
+                    color: Get.reactiveTheme.textTheme.bodyLarge!.color,
                   ),
                 ),
               ),
@@ -524,7 +550,7 @@ class SubscriptionView extends GetView<SubscriptionController> {
                 '  |  ',
                 style: TextStyle(
                   fontSize: 16.sp,
-                  color: DarkThemeColors.hintTextColor,
+                  color: Get.reactiveTheme.hintColor,
                 ),
               ),
               GestureDetector(
@@ -533,7 +559,7 @@ class SubscriptionView extends GetView<SubscriptionController> {
                   Strings.paymentIssue.tr,
                   style: TextStyle(
                     fontSize: 16.sp,
-                    color: DarkThemeColors.bodyTextColor,
+                    color: Get.reactiveTheme.textTheme.bodyLarge!.color,
                   ),
                 ),
               ),
@@ -554,7 +580,7 @@ class SubscriptionView extends GetView<SubscriptionController> {
                 Strings.yearlyAutoRenewCancelAnytime.tr,
                 style: TextStyle(
                   fontSize: 13.sp,
-                  color: DarkThemeColors.hintTextColor,
+                  color: Get.reactiveTheme.hintColor,
                 ),
               ),
             ],

+ 7 - 6
lib/app/widgets/info_card.dart

@@ -1,7 +1,8 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get.dart';
 import 'package:nomo/app/widgets/ix_image.dart';
-import 'package:nomo/config/theme/dark_theme_colors.dart';
+import 'package:nomo/config/theme/theme_extensions/theme_extension.dart';
 
 /// 信息卡片组件 - 用于显示带图标的信息列表
 /// 常用于订阅说明、功能介绍等场景
@@ -29,7 +30,7 @@ class InfoCard extends StatelessWidget {
             title!,
             style: TextStyle(
               fontSize: 16.sp,
-              color: DarkThemeColors.hintTextColor,
+              color: Get.reactiveTheme.hintColor,
               fontWeight: FontWeight.w500,
             ),
           ),
@@ -38,7 +39,7 @@ class InfoCard extends StatelessWidget {
         Container(
           padding: padding ?? EdgeInsets.all(16.w),
           decoration: BoxDecoration(
-            color: backgroundColor ?? DarkThemeColors.bgDisable,
+            color: backgroundColor ?? Get.reactiveTheme.cardColor,
             borderRadius: BorderRadius.circular(12.r),
           ),
           child: Column(
@@ -111,7 +112,7 @@ class _InfoItemWidget extends StatelessWidget {
                   child: Container(
                     width: 1,
                     margin: EdgeInsets.only(top: 8.h, bottom: 8.h),
-                    color: Colors.white.withValues(alpha: 0.1),
+                    color: Get.reactiveTheme.dividerColor,
                   ),
                 ),
             ],
@@ -129,7 +130,7 @@ class _InfoItemWidget extends StatelessWidget {
                     style: TextStyle(
                       fontSize: 14.sp,
                       height: 1.6,
-                      color: DarkThemeColors.bodyTextColor,
+                      color: Get.reactiveTheme.textTheme.bodyLarge!.color,
                       fontWeight: FontWeight.w500,
                     ),
                   ),
@@ -138,7 +139,7 @@ class _InfoItemWidget extends StatelessWidget {
                     item.description,
                     style: TextStyle(
                       fontSize: 12.sp,
-                      color: DarkThemeColors.hintTextColor,
+                      color: Get.reactiveTheme.textTheme.bodyLarge!.color,
                       height: 1.7,
                     ),
                   ),

+ 7 - 3
lib/config/theme/dark_theme_colors.dart

@@ -100,7 +100,11 @@ class DarkThemeColors {
   static const Color connectingIconColor = Color(0xFFEA9800);
   static const Color connectedIconColor = Color(0xFF5182E1);
 
-  static const Color homePremiumColor = Color(0xFFFCEFCF);
-  static const Color homeFreeColor = Color(0xFFFFFFFF);
-  static const Color homeTestColor = Color(0x0D2CD5FF);
+  static const Color homePremiumColor = Color(0x0DFFFFFF);
+  static const Color homeFreeColor = Color(0x0DFFFFFF);
+  static const Color homeTestColor = Color(0x0DFFFFFF);
+
+  static const Color homePremiumTextColor = Color(0xFFFFD58D);
+  static const Color homeFreeTextColor = Color(0xFF626778);
+  static const Color homeTestTextColor = Color(0xFF626778);
 }

+ 8 - 0
lib/config/theme/light_theme_colors.dart

@@ -82,4 +82,12 @@ class LightThemeColors {
   static const Color textBrand = Color(0xFFFFFFFF);
   static const Color strokes1 = Color(0xFFDCDFE6);
   static const Color strokes2 = Color(0xFFEBEDF0);
+
+  static const Color homePremiumColor = Color(0xFF7B4920);
+  static const Color homeFreeColor = Color(0xFFFFFFFF);
+  static const Color homeTestColor = Color(0xFFFFFFFF);
+
+  static const Color homePremiumTextColor = Color(0xFFFFFFFF);
+  static const Color homeFreeTextColor = Color(0xFF646776);
+  static const Color homeTestTextColor = Color(0xFF646776);
 }

+ 5 - 0
lib/config/translations/ar_AR/ar_ar_translation.dart

@@ -462,4 +462,9 @@ final Map<String, String> arAR = {
   Strings.pleaseEnterValidEmail: 'يرجى إدخال عنوان بريد إلكتروني صالح',
   Strings.feedbackSubmitted: 'تم إرسال الملاحظات، سنرد عليك قريباً',
   Strings.feedbackSubmitFailed: 'فشل الإرسال، يرجى المحاولة مرة أخرى لاحقاً',
+
+  // وحدات الوقت
+  Strings.days: 'أيام',
+  Strings.day: 'يوم',
+  Strings.hour: 'س',
 };

+ 5 - 0
lib/config/translations/de_DE/de_de_translation.dart

@@ -468,4 +468,9 @@ const Map<String, String> deDE = {
   Strings.pleaseEnterValidEmail: 'Bitte geben Sie eine gültige E-Mail-Adresse ein',
   Strings.feedbackSubmitted: 'Feedback gesendet, wir werden Ihnen bald antworten',
   Strings.feedbackSubmitFailed: 'Senden fehlgeschlagen, bitte später erneut versuchen',
+
+  // Zeiteinheiten
+  Strings.days: 'Tage',
+  Strings.day: 'Tag',
+  Strings.hour: 'Std',
 };

+ 5 - 0
lib/config/translations/en_US/en_us_translation.dart

@@ -474,4 +474,9 @@ Map<String, String> enUs = {
   Strings.followSystem: 'Follow System',
   Strings.darkMode: 'Dark',
   Strings.lightMode: 'Light',
+
+  // 时间单位
+  Strings.days: 'days',
+  Strings.day: 'day',
+  Strings.hour: 'h',
 };

+ 5 - 0
lib/config/translations/es_ES/es_es_translation.dart

@@ -473,4 +473,9 @@ const Map<String, String> esEs = {
   Strings.pleaseEnterValidEmail: 'Por favor ingresa una dirección de correo electrónico válida',
   Strings.feedbackSubmitted: 'Comentario enviado, te responderemos pronto',
   Strings.feedbackSubmitFailed: 'Error al enviar, por favor intenta de nuevo más tarde',
+
+  // Unidades de tiempo
+  Strings.days: 'días',
+  Strings.day: 'día',
+  Strings.hour: 'h',
 };

+ 5 - 0
lib/config/translations/fa_IR/fa_ir_translation.dart

@@ -468,4 +468,9 @@ const Map<String, String> faIR = {
   Strings.pleaseEnterValidEmail: 'لطفاً یک آدرس ایمیل معتبر وارد کنید',
   Strings.feedbackSubmitted: 'بازخورد ارسال شد، به زودی پاسخ خواهیم داد',
   Strings.feedbackSubmitFailed: 'ارسال ناموفق، لطفاً بعداً دوباره تلاش کنید',
+
+  // واحدهای زمان
+  Strings.days: 'روز',
+  Strings.day: 'روز',
+  Strings.hour: 'س',
 };

+ 5 - 0
lib/config/translations/fr_FR/fr_fr_translation.dart

@@ -474,4 +474,9 @@ const Map<String, String> frFR = {
   Strings.pleaseEnterValidEmail: 'Veuillez entrer une adresse e-mail valide',
   Strings.feedbackSubmitted: 'Commentaire envoyé, nous vous répondrons bientôt',
   Strings.feedbackSubmitFailed: 'Échec de l\'envoi, veuillez réessayer plus tard',
+
+  // Unités de temps
+  Strings.days: 'jours',
+  Strings.day: 'jour',
+  Strings.hour: 'h',
 };

+ 5 - 0
lib/config/translations/hi_IN/hi_in_translation.dart

@@ -337,4 +337,9 @@ Map<String, String> hiIN = {
   Strings.pleaseEnterValidEmail: 'कृपया एक मान्य ईमेल पता दर्ज करें',
   Strings.feedbackSubmitted: 'प्रतिक्रिया भेजी गई, हम जल्द ही आपको जवाब देंगे',
   Strings.feedbackSubmitFailed: 'भेजना विफल, कृपया बाद में पुनः प्रयास करें',
+
+  // समय इकाइयाँ
+  Strings.days: 'दिन',
+  Strings.day: 'दिन',
+  Strings.hour: 'घं',
 };

+ 5 - 0
lib/config/translations/id_ID/id_id_translation.dart

@@ -338,4 +338,9 @@ Map<String, String> idID = {
   Strings.pleaseEnterValidEmail: 'Silakan masukkan alamat email yang valid',
   Strings.feedbackSubmitted: 'Umpan balik terkirim, kami akan segera membalas',
   Strings.feedbackSubmitFailed: 'Gagal mengirim, silakan coba lagi nanti',
+
+  // Satuan waktu
+  Strings.days: 'hari',
+  Strings.day: 'hari',
+  Strings.hour: 'jam',
 };

+ 5 - 0
lib/config/translations/ja_JP/ja_jp_translation.dart

@@ -447,4 +447,9 @@ const Map<String, String> jaJP = {
   Strings.pleaseEnterValidEmail: '有効なメールアドレスを入力してください',
   Strings.feedbackSubmitted: 'フィードバックを送信しました。すぐにご返信いたします',
   Strings.feedbackSubmitFailed: '送信に失敗しました。後でもう一度お試しください',
+
+  // 時間単位
+  Strings.days: '日',
+  Strings.day: '日',
+  Strings.hour: '時間',
 };

+ 5 - 0
lib/config/translations/ko_KR/ko_kr_translation.dart

@@ -440,4 +440,9 @@ const Map<String, String> koKR = {
   Strings.pleaseEnterValidEmail: '유효한 이메일 주소를 입력해주세요',
   Strings.feedbackSubmitted: '피드백이 제출되었습니다. 곧 답변드리겠습니다',
   Strings.feedbackSubmitFailed: '제출 실패, 나중에 다시 시도해주세요',
+
+  // 시간 단위
+  Strings.days: '일',
+  Strings.day: '일',
+  Strings.hour: '시간',
 };

+ 5 - 0
lib/config/translations/my_MM/my_mm_translation.dart

@@ -476,4 +476,9 @@ const Map<String, String> myMM = {
   Strings.pleaseEnterValidEmail: 'တရားဝင်အီးမေးလ်လိပ်စာထည့်သွင်းပါ',
   Strings.feedbackSubmitted: 'အကြံပြုချက်ပေးပို့ပြီးပါပြီ၊ မကြာမီ ပြန်လည်ဖြေကြားပေးပါမည်',
   Strings.feedbackSubmitFailed: 'ပေးပို့ခြင်းမအောင်မြင်ပါ၊ နောက်မှထပ်ကြိုးစားပါ',
+
+  // အချိန်ယူနစ်များ
+  Strings.days: 'ရက်',
+  Strings.day: 'ရက်',
+  Strings.hour: 'နာရီ',
 };

+ 5 - 0
lib/config/translations/pt_BR/pt_br_translation.dart

@@ -468,4 +468,9 @@ Map<String, String> ptBR = {
   Strings.pleaseEnterValidEmail: 'Por favor, insira um endereço de e-mail válido',
   Strings.feedbackSubmitted: 'Feedback enviado, responderemos em breve',
   Strings.feedbackSubmitFailed: 'Falha no envio, por favor tente novamente mais tarde',
+
+  // Unidades de tempo
+  Strings.days: 'dias',
+  Strings.day: 'dia',
+  Strings.hour: 'h',
 };

+ 5 - 0
lib/config/translations/ru_RU/ru_ru_translation.dart

@@ -473,4 +473,9 @@ const Map<String, String> ruRU = {
   Strings.pleaseEnterValidEmail: 'Пожалуйста, введите действительный адрес электронной почты',
   Strings.feedbackSubmitted: 'Отзыв отправлен, мы скоро вам ответим',
   Strings.feedbackSubmitFailed: 'Отправка не удалась, пожалуйста, попробуйте позже',
+
+  // Единицы времени
+  Strings.days: 'дней',
+  Strings.day: 'день',
+  Strings.hour: 'ч',
 };

+ 14 - 0
lib/config/translations/strings_enum.dart

@@ -481,4 +481,18 @@ class Strings {
   static const String followSystem = 'Follow System';
   static const String darkMode = 'Dark';
   static const String lightMode = 'Light';
+
+  static const String membershipExpired = 'Membership Expired';
+  static const String membershipExpiredMessage =
+      'Your free trial has ended.\nSubscribe now to continue enjoying all premium features.';
+  static const String subscribeNow = 'Subscribe Now';
+
+  static const String subscriptionForWebTitle = 'Prompt';
+  static const String subscriptionForWebMessage =
+      'If the membership period is not updated after payment, please pull down the home page to refresh or restart the client to synchronize.';
+
+  // 时间单位
+  static const String days = 'days';
+  static const String day = 'day';
+  static const String hour = 'h';
 }

+ 5 - 0
lib/config/translations/th_TH/th_th_translation.dart

@@ -337,4 +337,9 @@ Map<String, String> thTH = {
   Strings.pleaseEnterValidEmail: 'กรุณากรอกที่อยู่อีเมลที่ถูกต้อง',
   Strings.feedbackSubmitted: 'ส่งความคิดเห็นแล้ว เราจะตอบกลับคุณเร็วๆ นี้',
   Strings.feedbackSubmitFailed: 'ส่งไม่สำเร็จ กรุณาลองใหม่ภายหลัง',
+
+  // หน่วยเวลา
+  Strings.days: 'วัน',
+  Strings.day: 'วัน',
+  Strings.hour: 'ชม.',
 };

+ 5 - 0
lib/config/translations/tk_TM/tk_tm_translation.dart

@@ -464,4 +464,9 @@ Map<String, String> tkTM = {
   Strings.pleaseEnterValidEmail: 'Dogry e-poçta salgysyny giriziň',
   Strings.feedbackSubmitted: 'Pikir iberildi, tiz wagtda jogap bereris',
   Strings.feedbackSubmitFailed: 'Ibermek şowsuz, soňra gaýtadan synanyşyň',
+
+  // Wagt birlikleri
+  Strings.days: 'gün',
+  Strings.day: 'gün',
+  Strings.hour: 'sag',
 };

+ 5 - 0
lib/config/translations/tl_PH/tl_ph_translation.dart

@@ -338,4 +338,9 @@ Map<String, String> tlPH = {
   Strings.pleaseEnterValidEmail: 'Mangyaring ilagay ang valid na email address',
   Strings.feedbackSubmitted: 'Naipadala ang feedback, magreresponde kami sa lalong madaling panahon',
   Strings.feedbackSubmitFailed: 'Nabigo ang pagpapadala, mangyaring subukan muli mamaya',
+
+  // Mga yunit ng oras
+  Strings.days: 'araw',
+  Strings.day: 'araw',
+  Strings.hour: 'oras',
 };

+ 5 - 0
lib/config/translations/tr_TR/tr_tr_translation.dart

@@ -338,4 +338,9 @@ Map<String, String> trTR = {
   Strings.pleaseEnterValidEmail: 'Lütfen geçerli bir e-posta adresi girin',
   Strings.feedbackSubmitted: 'Geri bildirim gönderildi, en kısa sürede yanıt vereceğiz',
   Strings.feedbackSubmitFailed: 'Gönderme başarısız, lütfen daha sonra tekrar deneyin',
+
+  // Zaman birimleri
+  Strings.days: 'gün',
+  Strings.day: 'gün',
+  Strings.hour: 'sa',
 };

+ 5 - 0
lib/config/translations/vi_VN/vi_vn_translation.dart

@@ -378,4 +378,9 @@ Map<String, String> viVN = {
   Strings.pleaseEnterValidEmail: 'Vui lòng nhập địa chỉ email hợp lệ',
   Strings.feedbackSubmitted: 'Phản hồi đã được gửi, chúng tôi sẽ trả lời bạn sớm',
   Strings.feedbackSubmitFailed: 'Gửi thất bại, vui lòng thử lại sau',
+
+  // Đơn vị thời gian
+  Strings.days: 'ngày',
+  Strings.day: 'ngày',
+  Strings.hour: 'giờ',
 };

+ 5 - 0
lib/config/translations/zh_TW/zh_tw_translation.dart

@@ -435,4 +435,9 @@ Map<String, String> zhTW = {
   Strings.followSystem: '跟隨系統',
   Strings.darkMode: '深色',
   Strings.lightMode: '淺色',
+
+  // 時間單位
+  Strings.days: '天',
+  Strings.day: '天',
+  Strings.hour: '小時',
 };

+ 2 - 1
pubspec.yaml

@@ -123,9 +123,10 @@ flutter:
   assets:
     - assets/images/
     - assets/images/streaming/
-    - assets/images/identity/
     - assets/images/round/
     - assets/images/html/
+    - assets/images/dark/
+    - assets/images/light/
     - assets/vectors/
     - assets/vectors/boost/
     - assets/vectors/status/