import 'package:auto_size_text/auto_size_text.dart'; import 'package:design/design.dart'; import 'package:guru_app/financial/iap/iap_model.dart'; import 'package:guru_ui/pages/store/store_page.dart'; import 'package:guru_ui/widget/image/adaptive_image.dart'; import 'package:guru_widgets/button/guru_button.dart'; import 'package:guru_widgets/theme/guru_theme.dart'; part 'bundle_card.g.dart'; @DesignSpec(width: 750, height: 388, specMode: SpecMode.nested) abstract class BundleCardDesignSpec implements BasicDesignSpec { @SpecEdgeInsets.only( top: SpecHeight(12), bottom: SpecHeight(18), start: SpecWidth(12), end: SpecWidth(12)) EdgeInsets get bundleCardPadding; @SpecEdgeInsets.only( top: SpecHeight(18), start: SpecWidth(24), end: SpecWidth(24), ) EdgeInsets get bundleInfoPadding; @SpecHeight(-56) double get bundleLabelTopSpcing; @SpecHeight(-40) double get bundleLabelRightSpcing; @SpecHeight(136) double get bundleLabelSize; @SpecAbsoluteFontSize(32) double get bundleTitleFontsize; @SpecAbsoluteFontSize(20) double get bundleSummaryFontsize; @SpecHeight(8) double get bundleTitleBottomSpcing; @SpecSize(SpecWidth(200), SpecHeight(80)) Size get bundleButtonSize; static BundleCardDesignSpec create(Size size, {Offset offset = Offset.zero}) => _BundleCardDesignSpec.from(size, offset: offset); } typedef BundleContaineBuilder = Widget Function( BuildContext, BundleCardDesignSpec); class BundleCardStyle { final String name; const BundleCardStyle.create(this.name); // 游戏内货币的资源条 static const BundleCardStyle igc = BundleCardStyle.create("igc"); } class BundleCardStyleTheme { final Color? titleColor; final Color? summaryColor; final GuruButtonStyle? buttonStyle; final Decoration? background; const BundleCardStyleTheme({ this.titleColor, this.summaryColor, this.buttonStyle, this.background, }); static const defaultTheme = BundleCardStyleTheme(); } class BundleCardModel { final IapProduct? product; final BundleItem bundleItem; final BundleCardStyleTheme styleTheme; final BundleCardDesignSpec designSpec; final VoidCallback onTap; BundleCardModel( {required this.product, required this.bundleItem, required this.styleTheme, required this.designSpec, required this.onTap}); } class BundleCard extends StatelessWidget { final BundleCardModel model; IapProduct? get product => model.product; BundleItem get bundleItem => model.bundleItem; BundleCardStyleTheme get styleTheme => model.styleTheme; BundleCardDesignSpec get designSpec => model.designSpec; const BundleCard({Key? key, required this.model}) : super(key: key); @override Widget build(BuildContext context) { return Container( width: double.infinity, padding: designSpec.bundleCardPadding, decoration: styleTheme.background ?? const BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(12)), gradient: LinearGradient( colors: [Color(0xFF913A95), Color(0xFFAD56B0)], begin: Alignment.centerLeft, end: Alignment.centerRight), boxShadow: [ BoxShadow( color: Color.fromRGBO(168, 117, 169, 1), offset: Offset(0, 2), ) ]), child: Stack( clipBehavior: Clip.none, children: [ Column( mainAxisSize: MainAxisSize.min, children: [ bundleItem.builder(context, designSpec), Padding(padding: designSpec.bundleInfoPadding, child: Row( children: [ Expanded(child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ AutoSizeText( bundleItem.title, minFontSize: 10, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( color: styleTheme.titleColor ?? Colors.white, fontWeight: GuruTheme.fwExtraBold, fontSize: designSpec.bundleTitleFontsize, height: 1.25), ), if (bundleItem.summary != null) Padding( padding: EdgeInsets.only( top: designSpec.bundleTitleBottomSpcing), child: AutoSizeText( bundleItem.summary!, minFontSize: 8, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( color: styleTheme.summaryColor ?? Colors.white, fontSize: designSpec.bundleSummaryFontsize, fontWeight: GuruTheme.fwMedium), )) ]) ), SizedBox(width: 4), GuruButton( size: designSpec.bundleButtonSize, sizeSpec: GuruButtonSizeSpec.s3, action: product != null ? product!.details.price : '1000000000', // summary: bundleItem.summary, style: styleTheme.buttonStyle, onPressed: () { model.onTap.call(); }) ], )), ], ), if (bundleItem.label != null) Positioned.directional( textDirection: Directionality.of(context), top: designSpec.bundleLabelTopSpcing, end: designSpec.bundleLabelRightSpcing, child: AdaptiveImage(bundleItem.label!, height: designSpec.bundleLabelSize)) ]), ); } }