|
...
|
...
|
@@ -8,6 +8,7 @@ import 'package:doublefeel_flutter/data/local/user_preferences_storage.dart'; |
|
|
|
import 'package:doublefeel_flutter/data/models/local/user_preferences.dart';
|
|
|
|
import 'package:doublefeel_flutter/l10n/l10n_extensions.dart';
|
|
|
|
import 'package:doublefeel_flutter/l10n/l10n_extensions.dart' as context;
|
|
|
|
import 'package:flutter/gestures.dart';
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:get/get.dart';
|
|
|
|
import 'package:intl/intl.dart';
|
|
...
|
...
|
@@ -410,7 +411,7 @@ class _LegalNotes extends StatelessWidget { |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class _LegalText extends StatelessWidget {
|
|
|
|
class _LegalText extends StatefulWidget {
|
|
|
|
const _LegalText({
|
|
|
|
required this.prefix,
|
|
|
|
required this.text,
|
|
...
|
...
|
@@ -425,6 +426,31 @@ class _LegalText extends StatelessWidget { |
|
|
|
final String? linkSuffix;
|
|
|
|
final VoidCallback? onLinkTap;
|
|
|
|
|
|
|
|
@override
|
|
|
|
State<_LegalText> createState() => _LegalTextState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _LegalTextState extends State<_LegalText> {
|
|
|
|
late final TapGestureRecognizer _linkRecognizer;
|
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
super.initState();
|
|
|
|
_linkRecognizer = TapGestureRecognizer()..onTap = widget.onLinkTap;
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void didUpdateWidget(covariant _LegalText oldWidget) {
|
|
|
|
super.didUpdateWidget(oldWidget);
|
|
|
|
_linkRecognizer.onTap = widget.onLinkTap;
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void dispose() {
|
|
|
|
_linkRecognizer.dispose();
|
|
|
|
super.dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
static const _baseStyle = TextStyle(
|
|
|
|
color: PurchaseColors.subtitle,
|
|
|
|
fontSize: 12,
|
|
...
|
...
|
@@ -441,48 +467,25 @@ class _LegalText extends StatelessWidget { |
|
|
|
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),
|
|
|
|
TextSpan(text: widget.text),
|
|
|
|
if (widget.linkText case final linkText?)
|
|
|
|
TextSpan(
|
|
|
|
text: linkText,
|
|
|
|
style: _linkStyle,
|
|
|
|
recognizer: widget.onLinkTap == null ? null : _linkRecognizer,
|
|
|
|
),
|
|
|
|
if (widget.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(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: [
|
|
|
|
Text(
|
|
|
|
prefix,
|
|
|
|
widget.prefix,
|
|
|
|
style: const TextStyle(
|
|
|
|
color: PurchaseColors.subtitle,
|
|
|
|
fontSize: 12,
|
|
...
|
...
|
@@ -490,17 +493,9 @@ class _LegalText extends StatelessWidget { |
|
|
|
),
|
|
|
|
),
|
|
|
|
Expanded(
|
|
|
|
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),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
child: Text.rich(
|
|
|
|
_buildTextSpan(),
|
|
|
|
textScaler: MediaQuery.textScalerOf(context),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
...
|
...
|
|