guru_sdk/guru_ui/lib/pages/store/purchase_card.dart

235 lines
7.5 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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/guru_widget.dart';
import 'package:guru_ui/localizations/ui_strings.dart';
import 'package:guru_ui/pages/store/store_design_spec.dart';
import 'package:guru_ui/pages/store/store_page.dart';
import 'package:guru_widgets/common/flexible_container.dart';
import 'package:guru_widgets/common/spacer.dart';
import 'package:guru_widgets/theme/guru_theme.dart';
import 'package:guru_ui/localizations/l10n/generated/app_localizations.dart';
part 'purchase_card.g.dart';
@DesignSpec(width: 210, height: 320, specMode: SpecMode.useSize)
abstract class PurchaseCardDesignSpec implements BasicDesignSpec {
@SpecRadius.circular(SpecHeight(24))
BorderRadius get cardRadius;
@SpecRadius.circular(SpecHeight(12))
BorderRadius get exhibitionRadius;
@SpecRect.fromLTRB(SpecHorizontal(12), SpecVertical(13), SpecHorizontal(12),
SpecVertical(106))
Rect get exhibitionPositionedRect;
@SpecEdgeInsets.only(
start: SpecHorizontal(12),
end: SpecHorizontal(12),
top: SpecVertical(22),
bottom: SpecVertical(2))
EdgeInsets get extraBonusPadding;
@SpecFontSize(18)
double get bonusFontSize;
@SpecAbsoluteFontSize(36)
double get quantityFontSize;
@SpecEdgeInsets.symmetric(horizontal: SpecHorizontal(12))
EdgeInsets get quantityPadding;
@SpecHeight(4)
double get quantityUnitSpacing;
@SpecHeight(34)
double get quantityUnitSize;
@SpecSize(SpecWidth(144), SpecHeight(112))
Size get illustrationSize;
@SpecEdgeInsets.only(top: SpecVertical(18), bottom: SpecVertical(12))
EdgeInsets get illustrationPadding;
@SpecHeight(12)
double get purchaseButtonTopSpacing;
@SpecAspectHeightSize(60, 2.83333333)
Size get purchaseButtonSize;
@SpecHeight(92, consistent: true)
double get labelSize;
@SpecHeight(88, consistent: true)
double get labelTopSpacing;
@SpecWidth(6)
double get labalEndSpacing;
static PurchaseCardDesignSpec from(Size size,
{Offset offset = Offset.zero}) =>
_PurchaseCardDesignSpec.from(size, offset: offset);
}
class PurchaseCardStyle {
final String name;
const PurchaseCardStyle.create(this.name);
// 游戏内货币的资源条
static const PurchaseCardStyle igc = PurchaseCardStyle.create("_igc");
}
class PurchaseCardStyleTheme {
// 额外Bonus的颜色如果不提供将填充黑色
final Color? extraBonusColor;
// 数量的颜色,如果不提供将填充黑色
final Color? quantityColor;
// 数量前缀的单位icon, 如果不提供将不显示
final QuantityPrefix? quantityPrefix;
// 数量前前缀的单位icon, 如果不提供将不显示
final String? quantityUnit;
// 是否使用千分位分隔符
final bool? useThousandsSeparator;
// 展览区域的渐变背景,如果不提供将不显示
final Gradient? exhibitionGradient;
// 卡片组中各个卡版的默认背景色如果不提供将会使用GuruTheme中的containerColor替代
final Color? backgroundColor;
// PurchaseButton的样式
final GuruButtonStyle? purchaseButtonStyle;
PurchaseCardStyleTheme({
this.extraBonusColor,
this.quantityColor,
this.quantityPrefix,
this.quantityUnit,
this.exhibitionGradient,
this.backgroundColor,
this.useThousandsSeparator = true,
this.purchaseButtonStyle,
});
}
class PurchaseCardModel {
final IapProduct? product;
final CardItem cardItem;
final PurchaseCardStyleTheme styleTheme;
final PurchaseCardDesignSpec designSpec;
final VoidCallback onTap;
PurchaseCardModel(
{required this.product,
required this.cardItem,
required this.styleTheme,
required this.designSpec,
required this.onTap});
}
class PurchaseCard extends StatelessWidget {
final PurchaseCardModel model;
IapProduct? get product => model.product;
CardItem get cardItem => model.cardItem;
PurchaseCardStyleTheme get styleTheme => model.styleTheme;
PurchaseCardDesignSpec get designSpec => model.designSpec;
const PurchaseCard({Key? key, required this.model}) : super(key: key);
@override
Widget build(BuildContext context) {
final extraBonus = cardItem.extraBonus ?? 0;
final uiStrings = UIStrings.get();
return FlexibleContainer(
width: designSpec.measuredSize.width,
height: designSpec.measuredSize.height,
radius: designSpec.cardRadius,
color: styleTheme.backgroundColor,
child: Stack(fit: StackFit.expand, children: [
Positioned(
left: designSpec.exhibitionPositionedRect.left,
right: designSpec.exhibitionPositionedRect.right,
top: designSpec.exhibitionPositionedRect.top,
bottom: designSpec.exhibitionPositionedRect.bottom,
child: DecoratedBox(
decoration: BoxDecoration(
borderRadius: designSpec.exhibitionRadius,
gradient: styleTheme.exhibitionGradient))),
Column(crossAxisAlignment: CrossAxisAlignment.center, children: [
Padding(
padding: designSpec.extraBonusPadding,
child: Text(
extraBonus > 0
? "${(extraBonus * 100).toInt()}% ${uiStrings.bonus}"
: " ",
style: TextStyle(
fontSize: designSpec.bonusFontSize,
fontWeight: GuruTheme.fwSemiBold,
color: styleTheme.extraBonusColor ??
const Color(0xFFFF2830)),
)),
Padding(
padding: designSpec.quantityPadding,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (styleTheme.quantityUnit != null) ...[
Image.asset(styleTheme.quantityUnit!,
width: designSpec.quantityUnitSize,
height: designSpec.quantityUnitSize),
SizedSpacer(width: designSpec.quantityUnitSpacing)
],
AutoSizeText(
cardItem.quantity.toString(),
minFontSize: 5,
style: TextStyle(
fontSize: designSpec.quantityFontSize,
fontWeight: GuruTheme.fwBold,
color: styleTheme.quantityColor),
)
],
),
),
Padding(
padding: designSpec.illustrationPadding,
child: AdaptiveImage(
cardItem.illustration,
width: designSpec.illustrationSize.width,
height: designSpec.illustrationSize.height,
fit: BoxFit.cover
),
),
GuruButton(
size: designSpec.purchaseButtonSize,
sizeSpec: GuruButtonSizeSpec.s5,
style: GuruButtonStyle.purchase,
action: product != null ? product!.details.price : '1000000000',
onPressed: () {
model.onTap.call();
},
)
]),
if (cardItem.label != null)
Positioned.directional(textDirection: Directionality.of(context),
top: designSpec.labelTopSpacing,
end: designSpec.labalEndSpacing,
child: AdaptiveImage(
cardItem.label!,
width: designSpec.labelSize,
height: designSpec.labelSize,
))
]));
}
}