|
...
|
...
|
@@ -38,13 +38,15 @@ class PurchaseView extends GetView<PurchaseController> { |
|
|
|
child: SingleChildScrollView(
|
|
|
|
controller: controller.scrollController,
|
|
|
|
physics: const ClampingScrollPhysics(),
|
|
|
|
padding: const EdgeInsets.only(bottom: 170),
|
|
|
|
padding: EdgeInsets.only(
|
|
|
|
bottom: 170 + MediaQuery.paddingOf(context).bottom,
|
|
|
|
),
|
|
|
|
child: Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: [
|
|
|
|
const _HeroHeader(),
|
|
|
|
Padding(
|
|
|
|
padding: EdgeInsets.only(left: 18, top: 9.h),
|
|
|
|
padding: EdgeInsets.only(left: 18, top: 9.h),
|
|
|
|
child: Text(
|
|
|
|
context.l10n.purchaseHeroTitle,
|
|
|
|
style: const TextStyle(
|
|
...
|
...
|
@@ -299,6 +301,57 @@ class _LegalText extends StatelessWidget { |
|
|
|
final String? linkSuffix;
|
|
|
|
final VoidCallback? onLinkTap;
|
|
|
|
|
|
|
|
static const _baseStyle = TextStyle(
|
|
|
|
color: PurchaseColors.subtitle,
|
|
|
|
fontSize: 12,
|
|
|
|
height: 1.4,
|
|
|
|
);
|
|
|
|
|
|
|
|
static const _linkStyle = TextStyle(
|
|
|
|
color: Color(0xFF845EEE),
|
|
|
|
fontWeight: FontWeight.w500,
|
|
|
|
decoration: TextDecoration.underline,
|
|
|
|
decorationColor: Color(0xFF845EEE),
|
|
|
|
);
|
|
|
|
|
|
|
|
TextSpan _buildTextSpan() => TextSpan(
|
|
|
|
style: _baseStyle,
|
|
|
|
children: [
|
|
|
|
TextSpan(text: text),
|
|
|
|
if (linkText case final linkText?)
|
|
|
|
TextSpan(text: linkText, style: _linkStyle),
|
|
|
|
if (linkSuffix case final linkSuffix?) TextSpan(text: linkSuffix),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
|
|
|
|
void _handleTapUp(
|
|
|
|
BuildContext context,
|
|
|
|
BoxConstraints constraints,
|
|
|
|
TapUpDetails details,
|
|
|
|
) {
|
|
|
|
final linkText = this.linkText;
|
|
|
|
if (linkText == null || onLinkTap == null) return;
|
|
|
|
|
|
|
|
final painter = TextPainter(
|
|
|
|
text: _buildTextSpan(),
|
|
|
|
textDirection: Directionality.of(context),
|
|
|
|
textScaler: MediaQuery.textScalerOf(context),
|
|
|
|
)..layout(maxWidth: constraints.maxWidth);
|
|
|
|
final linkStart = text.length;
|
|
|
|
final linkBoxes = painter.getBoxesForSelection(
|
|
|
|
TextSelection(
|
|
|
|
baseOffset: linkStart,
|
|
|
|
extentOffset: linkStart + linkText.length,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
|
|
|
if (linkBoxes.any(
|
|
|
|
(box) => box.toRect().inflate(10).contains(details.localPosition),
|
|
|
|
)) {
|
|
|
|
onLinkTap!.call();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return Row(
|
|
...
|
...
|
@@ -313,38 +366,16 @@ class _LegalText extends StatelessWidget { |
|
|
|
),
|
|
|
|
),
|
|
|
|
Expanded(
|
|
|
|
child: Text.rich(
|
|
|
|
TextSpan(
|
|
|
|
children: [
|
|
|
|
TextSpan(text: text),
|
|
|
|
if (linkText case final linkText?)
|
|
|
|
WidgetSpan(
|
|
|
|
alignment: PlaceholderAlignment.baseline,
|
|
|
|
baseline: TextBaseline.alphabetic,
|
|
|
|
child: GestureDetector(
|
|
|
|
behavior: HitTestBehavior.opaque,
|
|
|
|
onTap: onLinkTap,
|
|
|
|
child: Text(
|
|
|
|
linkText,
|
|
|
|
style: const TextStyle(
|
|
|
|
color: Color(0xFF845EEE),
|
|
|
|
fontSize: 12,
|
|
|
|
height: 1.4,
|
|
|
|
fontWeight: FontWeight.w500,
|
|
|
|
decoration: TextDecoration.underline,
|
|
|
|
decorationColor: Color(0xFF845EEE),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
if (linkSuffix case final linkSuffix?)
|
|
|
|
TextSpan(text: linkSuffix),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
style: const TextStyle(
|
|
|
|
color: PurchaseColors.subtitle,
|
|
|
|
fontSize: 12,
|
|
|
|
height: 1.4,
|
|
|
|
child: LayoutBuilder(
|
|
|
|
builder: (context, constraints) => GestureDetector(
|
|
|
|
behavior: HitTestBehavior.opaque,
|
|
|
|
onTapUp: linkText == null || onLinkTap == null
|
|
|
|
? null
|
|
|
|
: (details) => _handleTapUp(context, constraints, details),
|
|
|
|
child: Text.rich(
|
|
|
|
_buildTextSpan(),
|
|
|
|
textScaler: MediaQuery.textScalerOf(context),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
...
|
...
|
|