193 lines
5.9 KiB
Dart
193 lines
5.9 KiB
Dart
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<T> = 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))
|
|
]),
|
|
);
|
|
}
|
|
}
|