Преглед на файлове

adapt for normal product view

Destiny преди 8 месеца
родител
ревизия
32a3d87b75
променени са 1 файла, в които са добавени 302 реда и са изтрити 209 реда
  1. 302 209
      lib/module/store/discount/discount_view.dart

+ 302 - 209
lib/module/store/discount/discount_view.dart

@@ -1,5 +1,7 @@
 import 'dart:async';
-
+import 'dart:ffi';
+import 'package:intl/intl.dart';
+import 'package:clean/data/bean/store_item.dart';
 import 'package:clean/base/base_page.dart';
 import 'package:clean/module/store/discount/discount_controller.dart';
 import 'package:clean/utils/expand.dart';
@@ -31,6 +33,8 @@ class DiscountPage extends BasePage<DiscountController> {
 
       bool hasUsedFreeTrial = false;
       bool canShowFreeTrial = isFreeItem && !hasUsedFreeTrial;
+
+      StoreItem? freeItem = controller.storeItems.firstWhereOrNull((element) => element.freeTrialName != null);
       return Scaffold(
         backgroundColor: "#05050D".color,
         body: Stack(
@@ -46,25 +50,22 @@ class DiscountPage extends BasePage<DiscountController> {
                     // 创建一个1分钟的倒计时
                     CountdownTimer(duration: const Duration(minutes: 1)),
                     SizedBox(height: 40.h),
-                    _DiscountFreeTrialSpecialRow(
-                      title: '3-DAY FREE TRIAL',
-                      desc: 'Then \$6.99/week only \$0.54/day',
-                      isSelected: canShowFreeTrial,
-                      onSelect: (title) {
-                        if (isFreeItem) {
-                          controller.currentSelectedStoreItem.value = null;
-                        } else {
-                          controller.currentSelectedStoreItem.value = controller.storeItems.firstWhere((element) => element.freeTrialName != "");
-                        }
-                      },
-                    ),
+                    if (freeItem != null)
+                      _DiscountFreeTrialSpecialRow(
+                        item: freeItem,
+                        isSelected: canShowFreeTrial,
+                        // canStarFreeTrail: freeItem.freeTrialName != "" && controller.isFree.value,
+                        canStarFreeTrail: true,
+                        onSelect: (title) {
+                          controller.currentSelectedStoreItem.value = freeItem;
+                        },
+                      ),
                     SizedBox(height: 40.h),
                     _FeaturesPreview(),
                     SizedBox(height: 40.h),
                     _MorePlansSection(),
-                    SizedBox(height: 40.h),
-
-                    // 撑高
+                    SizedBox(height: 5.h),
+                    _OtherPlansSection(items: controller.storeItems.where((element) => element.freeTrialName == null).toList(), controller: controller),
                     SizedBox(height: 100.h),
                   ],
                 ),
@@ -73,26 +74,16 @@ class DiscountPage extends BasePage<DiscountController> {
             SafeArea(
               top: false,
               child: Column(
-                mainAxisSize: MainAxisSize.min,
+                mainAxisSize: MainAxisSize.max,
                 children: [
                   Spacer(),
                   Container(
-                    decoration: BoxDecoration(
-                      gradient: LinearGradient(
-                        begin: Alignment.topCenter,
-                        end: Alignment.bottomCenter,
-                        colors: [
-                          "#05050D".color.withOpacity(0),
-                          "#05050D".color,
-                        ],
-                      ),
+                    width: double.infinity,
+                    child: _PurchaseSection(
+                      isShowFree: canShowFreeTrial,
+                      controller: controller,
                     ),
-                    height: 20.h,
-                  ),
-                  _PurchaseSection(
-                    isShowFree: canShowFreeTrial,
-                    controller: controller,
-                  ),
+                  )
                 ],
               ),
             ),
@@ -183,7 +174,7 @@ class _FeaturesPreview extends StatelessWidget {
     return InfinitePreviewPageView(
       height: 98.h,
       autoPlay: true,
-      autoPlayDuration: const Duration(seconds: 5),
+      autoPlayDuration: const Duration(seconds: 3),
       items: [
         PreviewItem(
           title: 'One-click Remove Similar Photos',
@@ -219,78 +210,90 @@ class _PurchaseSection extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return Column(
-      children: [
-        Text(
-          isShowFree
-              ?  ""
-              : "Auto-renewalable.Cancel anytime",
-          style: TextStyle(
-            color: Colors.white.withOpacity(0.8),
-            fontSize: 12.sp,
-          ),
+    return Container(
+      decoration: BoxDecoration(
+        gradient: LinearGradient(
+          begin: Alignment.topCenter,
+          end: Alignment.bottomCenter,
+          colors: [
+            "000000".color.withOpacity(0),
+            "000000".color,
+          ],
         ),
-        SizedBox(height: 1.h),
-        GestureDetector(
-          onTap: () {
-            controller.onBuyClick();
-          },
-          child: Container(
-            width: 312.w,
-            height: 48.h,
-            decoration: BoxDecoration(
-              color: "#0279FB".color,
-              borderRadius: BorderRadius.all(
-                Radius.circular(24.r),
-              ),
-            ),
-            child: Center(
-              child: Text(
-                isShowFree ? "START FREE TRIAL" : "Continue",
-                style: TextStyle(
-                  color: Colors.white,
-                  fontWeight: FontWeight.w700,
-                  fontSize: 16.sp,
-                ),
-              ),
+      ),
+      child: Column(
+        children: [
+          Text(
+            isShowFree
+                ?  ""
+                : "Auto-renewalable.Cancel anytime",
+            style: TextStyle(
+              color: Colors.white.withOpacity(0.8),
+              fontSize: 12.sp,
             ),
           ),
-        ),
-        SizedBox(height: 5.h),
-        isShowFree ?
-        Text("No payment now!",
-          style: TextStyle(
-            color: "#57C87A".color,
-            fontSize: 12.sp,
-            fontWeight: FontWeight.w500,
-          ),
-        )
-            :
-        Container(
-          alignment: Alignment.center,
-          width: double.infinity,
-          child: Row(
-            mainAxisAlignment: MainAxisAlignment.center,
-            children: [
-              GestureDetector(
-                onTap: () {
-                  controller.onBuyClick();
-                },
-                child: Text("Privacy Policy", style: TextStyle(color: Colors.white.withOpacity(0.8), fontSize: 12.sp, fontWeight: FontWeight.w400)),
+          SizedBox(height: 1.h),
+          GestureDetector(
+            onTap: () {
+              controller.onBuyClick();
+            },
+            child: Container(
+              width: 312.w,
+              height: 48.h,
+              decoration: BoxDecoration(
+                color: "#0279FB".color,
+                borderRadius: BorderRadius.all(
+                  Radius.circular(24.r),
+                ),
               ),
-              SizedBox(width: 8.w),
-              Text("|", style: TextStyle(color: Colors.white.withOpacity(0.8), fontSize: 12.sp, fontWeight: FontWeight.w400)),
-              SizedBox(width: 8.w),
-              GestureDetector(
-                onTap: () {
-                  controller.onBuyClick();
-                },
-                child: Text("Privacy Policy", style: TextStyle(color: Colors.white.withOpacity(0.8), fontSize: 12.sp, fontWeight: FontWeight.w400)),
+              child: Center(
+                child: Text(
+                  isShowFree ? "START FREE TRIAL" : "Continue",
+                  style: TextStyle(
+                    color: Colors.white,
+                    fontWeight: FontWeight.w700,
+                    fontSize: 16.sp,
+                  ),
+                ),
               ),
-            ],
+            ),
           ),
-        )
-      ],
+          SizedBox(height: 5.h),
+          isShowFree ?
+          Text("No payment now!",
+            style: TextStyle(
+              color: "#57C87A".color,
+              fontSize: 12.sp,
+              fontWeight: FontWeight.w500,
+            ),
+          )
+              :
+          Container(
+            alignment: Alignment.center,
+            width: double.infinity,
+            child: Row(
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: [
+                GestureDetector(
+                  onTap: () {
+                    controller.onBuyClick();
+                  },
+                  child: Text("Privacy Policy", style: TextStyle(color: Colors.white.withOpacity(0.8), fontSize: 12.sp, fontWeight: FontWeight.w400)),
+                ),
+                SizedBox(width: 8.w),
+                Text("|", style: TextStyle(color: Colors.white.withOpacity(0.8), fontSize: 12.sp, fontWeight: FontWeight.w400)),
+                SizedBox(width: 8.w),
+                GestureDetector(
+                  onTap: () {
+                    controller.onBuyClick();
+                  },
+                  child: Text("Privacy Policy", style: TextStyle(color: Colors.white.withOpacity(0.8), fontSize: 12.sp, fontWeight: FontWeight.w400)),
+                ),
+              ],
+            ),
+          )
+        ],
+      ),
     );
   }
 }
@@ -316,133 +319,223 @@ class _MorePlansSection extends StatelessWidget {
   }
 }
 
+class _OtherPlansSection extends StatelessWidget {
+  final List<StoreItem> items;
+  final DiscountController controller;
+  const _OtherPlansSection({Key? key, required this.items, required this.controller}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.center,
+      children: [
+        ...items.map((item) => Padding(
+          padding: EdgeInsets.only(bottom: 12.h),
+          child: _DiscountFreeTrialSpecialRow(
+            item: item,
+            isSelected: controller.currentSelectedStoreItem.value?.id == item.id,
+            canStarFreeTrail: item.freeTrialName != null && controller.isFree.value,
+            onSelect: (item) {
+              controller.currentSelectedStoreItem.value = item;
+            },
+          ),
+        )).toList(),
+      ],
+    );
+  }
+}
+
 class _DiscountFreeTrialSpecialRow extends StatelessWidget {
-  final String title;
-  final String desc;
+  final StoreItem item;
   final bool isSelected;
-  final Function(String) onSelect;
+  final bool canStarFreeTrail;
+  final Function(StoreItem) onSelect;
 
-  const _DiscountFreeTrialSpecialRow({Key? key, required this.title, required this.desc, required this.isSelected, required this.onSelect}) : super(key: key);
+  const _DiscountFreeTrialSpecialRow({Key? key, required this.item, required this.isSelected, required this.canStarFreeTrail, required this.onSelect}) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
+    // 价格信息容器
+    Widget buildPriceInfoContainer() {
+      return Positioned(
+        bottom: -18.h,
+        child: Container(
+            alignment: Alignment.bottomCenter,
+            height: 43.h,
+            decoration: BoxDecoration(
+              color: '#1B2231'.color,
+              borderRadius: BorderRadius.circular(12.r),
+            ),
+            child: Padding(
+              padding: EdgeInsets.only(top: 14.h, left: 7.w, right: 9.w, bottom: 2.h),
+              child: Text(
+                  item.freeTrialPriceDesc ?? item.priceDesc ?? "",
+                  style: TextStyle(
+                      color: '#ffffff'.color.withOpacity(0.7),
+                      fontSize: 12,
+                      fontWeight: FontWeight.w400
+                  )
+              ),
+            )
+        ),
+      );
+    }
+
+    // 试用名称内容
+    Widget buildTrialNameContent() {
+      return Padding(
+        padding: EdgeInsets.symmetric(vertical: 7.h, horizontal: 12.w),
+        child: SizedBox(
+          width: double.infinity,
+          child: Column(
+            mainAxisAlignment: MainAxisAlignment.center,
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              Text(
+                item.freeTrialName ?? item.name,
+                style: TextStyle(
+                  color: isSelected ? '#FFe168'.color : '#ffffff'.color,
+                  fontSize: 22.sp,
+                  fontWeight: FontWeight.w900,
+                ),
+              ),
+            ],
+          ),
+        ),
+      );
+    }
+
+    Widget buildNormalProductContent() {
+      final formatter = NumberFormat.currency(
+        symbol: '\$',
+        decimalDigits: 2,
+      );
+      var amount = formatter.format(item.amount / 100);
+
+      return Padding(
+          padding: EdgeInsets.symmetric(vertical: 7.h, horizontal: 12.w),
+          child: Row(
+            children: [
+              Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                mainAxisAlignment: MainAxisAlignment.center,
+                children: [
+                  Text(item.name, style: TextStyle(color: '#ffffff'.color, fontSize: 16.sp, fontWeight: FontWeight.w700)),
+                  Text(item.priceDesc ?? "", style: TextStyle(color: '#ffffff'.color.withOpacity(0.6), fontSize: 12.sp, fontWeight: FontWeight.w400)),
+                ],
+              ),
+              Spacer(),
+              Text(amount, style: TextStyle(color: '#ffffff'.color, fontSize: 16.sp, fontWeight: FontWeight.w700)),
+            ],
+          )
+      );
+    }
+
+    // 免费标签的容器
+    Widget buildBadgeContainer() {
+      return Container(
+        padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h),
+        decoration: BoxDecoration(
+            gradient: LinearGradient(
+              begin: Alignment.centerLeft,
+              end: Alignment.centerRight,
+              colors: [
+                '#53CDFE'.color,
+                '#0279FB'.color,
+              ],
+            ),
+            borderRadius: BorderRadius.all(Radius.circular(20.w))
+        ),
+        child: Text(
+          'No payment now!',
+          style: TextStyle(
+            color: Colors.white,
+            fontSize: 12.sp,
+            fontWeight: FontWeight.w700,
+          ),
+        ),
+      );
+    }
+
+    // 免费标签的图标
+    Widget buildBadgeIcon() {
+      return Positioned(
+          left: -22,
+          child: Assets.images.iconStoreFree.image(width: 30.w, height: 30.w)
+      );
+    }
+
+    // 免费试用标签
+    Widget buildFreeTrialBadge() {
+      return Positioned(
+          top: -14,
+          right: 10,
+          child: Stack(
+            clipBehavior: Clip.none,
+            alignment: Alignment.centerLeft,
+            children: [
+              buildBadgeContainer(),
+              buildBadgeIcon(),
+            ],
+          )
+      );
+    }
+
+    // 主容器
+    Widget buildMainContainer() {
+      return Container(
+        padding: EdgeInsets.all(2),
+        decoration: isSelected ? BoxDecoration(
+          gradient: LinearGradient(
+              begin: Alignment.topLeft,
+              end: Alignment.bottomRight,
+              colors: [
+                '#D2A3FF'.color,
+                '#419CFF'.color,
+                '#01D0FF'.color,
+              ]
+          ),
+          borderRadius: BorderRadius.circular(20.r),
+        ) : BoxDecoration(
+          color: '#ffffff'.color.withOpacity(0.2),
+          borderRadius: BorderRadius.circular(20.r),
+        ),
+        child: Container(
+          height: 74.w,
+          decoration: BoxDecoration(
+            color: isSelected ? '#111f4b'.color : '000000'.color,
+            borderRadius: BorderRadius.circular(18.r),
+          ),
+          child: Stack(
+            clipBehavior: Clip.none,
+            children: [
+              if (canStarFreeTrail) buildTrialNameContent() else buildNormalProductContent(),
+              // 右上角FREE标签
+              if (canStarFreeTrail) buildFreeTrialBadge(),
+            ],
+          ),
+        ),
+      );
+    }
+
     return Container(
       margin: EdgeInsets.symmetric(horizontal: 15.w),
       child: GestureDetector(
         onTap: () {
-          onSelect(title);
+          onSelect(item);
         },
         child: Stack(
           alignment: Alignment.bottomRight,
           clipBehavior: Clip.none,
           children: [
-            Positioned(
-              bottom: -18.h,
-              child: Container(
-                  alignment: Alignment.bottomCenter,
-                  height: 43.h,
-                  decoration: BoxDecoration(
-                    color: '#1B2231'.color,
-                    borderRadius: BorderRadius.circular(12.r),
-                  ),
-                  child: Padding(
-                    padding: EdgeInsets.only(top: 14.h, left: 7.w, right: 9.w, bottom: 2.h),
-                    child: Text(desc, style: TextStyle(color: '#ffffff'.color.withOpacity(0.7), fontSize: 12, fontWeight: FontWeight.w400)),
-                  )
-              ),
-            ),
-            Container(
-              padding: EdgeInsets.all(2),
-              decoration: BoxDecoration(
-                gradient: LinearGradient(
-                    begin: Alignment.topLeft,
-                    end: Alignment.bottomRight,
-                    colors: isSelected ? [
-                      '#D2A3FF'.color,
-                      '#419CFF'.color,
-                      '#01D0FF'.color,
-                    ] : [
-                      '#33FFFFFF'.color,
-                      '#33FFFFFF'.color,
-                      '#33FFFFFF'.color,
-                    ]
-                ),
-                borderRadius: BorderRadius.circular(20.r),
-              ),
-              child: Container(
-                height: 74.w,
-                decoration: BoxDecoration(
-                  color: isSelected ? '#111f4b'.color : '000000'.color,
-                  borderRadius: BorderRadius.circular(18.r),
-                ),
-                child: Stack(
-                  clipBehavior: Clip.none,
-                  children: [
-                    Padding(
-                      padding: EdgeInsets.symmetric(horizontal: 15),
-                      child: SizedBox(
-                        width: double.infinity,
-                        height: double.infinity,
-                        child: Column(
-                          mainAxisAlignment: MainAxisAlignment.center,
-                          crossAxisAlignment: CrossAxisAlignment.start,
-                          children: [
-                            Text(
-                              title,
-                              style: TextStyle(
-                                color: isSelected ? '#FFe168'.color : '#ffffff'.color,
-                                fontSize: 22.sp,
-                                fontWeight: FontWeight.w900,
-                              ),
-                            ),
-                          ],
-                        ),
-                      ),
-                    ),
-                    // 右上角FREE标签
-                    if (isSelected)
-                      Positioned(
-                          top: -14,
-                          right: 10,
-                          child:Stack(
-                            clipBehavior: Clip.none,
-                            alignment: Alignment.centerLeft,
-                            children: [
-                              Container(
-                                padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h),
-                                decoration: BoxDecoration(
-                                    gradient: LinearGradient(
-                                      begin: Alignment.centerLeft,
-                                      end: Alignment.centerRight,
-                                      colors: [
-                                        '#53CDFE'.color,
-                                        '#0279FB'.color,
-                                      ],
-                                    ),
-                                    borderRadius: BorderRadius.all(Radius.circular(20.w))
-                                ),
-                                child: Text(
-                                  'No payment now!',
-                                  style: TextStyle(
-                                    color: Colors.white,
-                                    fontSize: 12.sp,
-                                  ),
-                                ),
-                              ),
-                              Positioned(
-                                  left: -22,
-                                  child: Assets.images.iconStoreFree.image(width: 30.w, height: 30.w)
-                              )
-                            ],
-                          )
-                      ),
-                  ],
-                ),
-              ),
-            )
+            if (canStarFreeTrail) buildPriceInfoContainer(),
+            buildMainContainer(),
           ],
         ),
       ),
     );
   }
-}
+}
+
+
+