Commit 67367a1106c39791136e1784bb17b78b0cfb860f

Authored by 刘宏哲
1 parent 390702b6

feat(app): bug fixed

  1 +import 'package:doublefeel_flutter/app/modules/login/views/email_login_contact_us_bottom_sheet.dart';
1 import 'package:doublefeel_flutter/core/logging/app_logger.dart'; 2 import 'package:doublefeel_flutter/core/logging/app_logger.dart';
2 import 'package:doublefeel_flutter/core/network/api/pay_api.dart'; 3 import 'package:doublefeel_flutter/core/network/api/pay_api.dart';
3 import 'package:doublefeel_flutter/core/network/api/vip_api.dart'; 4 import 'package:doublefeel_flutter/core/network/api/vip_api.dart';
@@ -176,7 +177,7 @@ class MembershipDetailController extends GetxController { @@ -176,7 +177,7 @@ class MembershipDetailController extends GetxController {
176 } 177 }
177 178
178 void openContactUs() { 179 void openContactUs() {
179 - Get.toNamed(Routes.SUBMIT_FEEDBACK); 180 + feedbackCompat(pageName: 'Subscription page');
180 } 181 }
181 182
182 Future<void> manageSubscription() async { 183 Future<void> manageSubscription() async {
@@ -8,6 +8,7 @@ import 'package:doublefeel_flutter/data/local/user_preferences_storage.dart'; @@ -8,6 +8,7 @@ import 'package:doublefeel_flutter/data/local/user_preferences_storage.dart';
8 import 'package:doublefeel_flutter/data/models/local/user_preferences.dart'; 8 import 'package:doublefeel_flutter/data/models/local/user_preferences.dart';
9 import 'package:doublefeel_flutter/l10n/l10n_extensions.dart'; 9 import 'package:doublefeel_flutter/l10n/l10n_extensions.dart';
10 import 'package:doublefeel_flutter/l10n/l10n_extensions.dart' as context; 10 import 'package:doublefeel_flutter/l10n/l10n_extensions.dart' as context;
  11 +import 'package:flutter/gestures.dart';
11 import 'package:flutter/material.dart'; 12 import 'package:flutter/material.dart';
12 import 'package:get/get.dart'; 13 import 'package:get/get.dart';
13 import 'package:intl/intl.dart'; 14 import 'package:intl/intl.dart';
@@ -410,7 +411,7 @@ class _LegalNotes extends StatelessWidget { @@ -410,7 +411,7 @@ class _LegalNotes extends StatelessWidget {
410 } 411 }
411 } 412 }
412 413
413 -class _LegalText extends StatelessWidget { 414 +class _LegalText extends StatefulWidget {
414 const _LegalText({ 415 const _LegalText({
415 required this.prefix, 416 required this.prefix,
416 required this.text, 417 required this.text,
@@ -425,6 +426,31 @@ class _LegalText extends StatelessWidget { @@ -425,6 +426,31 @@ class _LegalText extends StatelessWidget {
425 final String? linkSuffix; 426 final String? linkSuffix;
426 final VoidCallback? onLinkTap; 427 final VoidCallback? onLinkTap;
427 428
  429 + @override
  430 + State<_LegalText> createState() => _LegalTextState();
  431 +}
  432 +
  433 +class _LegalTextState extends State<_LegalText> {
  434 + late final TapGestureRecognizer _linkRecognizer;
  435 +
  436 + @override
  437 + void initState() {
  438 + super.initState();
  439 + _linkRecognizer = TapGestureRecognizer()..onTap = widget.onLinkTap;
  440 + }
  441 +
  442 + @override
  443 + void didUpdateWidget(covariant _LegalText oldWidget) {
  444 + super.didUpdateWidget(oldWidget);
  445 + _linkRecognizer.onTap = widget.onLinkTap;
  446 + }
  447 +
  448 + @override
  449 + void dispose() {
  450 + _linkRecognizer.dispose();
  451 + super.dispose();
  452 + }
  453 +
428 static const _baseStyle = TextStyle( 454 static const _baseStyle = TextStyle(
429 color: PurchaseColors.subtitle, 455 color: PurchaseColors.subtitle,
430 fontSize: 12, 456 fontSize: 12,
@@ -441,48 +467,25 @@ class _LegalText extends StatelessWidget { @@ -441,48 +467,25 @@ class _LegalText extends StatelessWidget {
441 TextSpan _buildTextSpan() => TextSpan( 467 TextSpan _buildTextSpan() => TextSpan(
442 style: _baseStyle, 468 style: _baseStyle,
443 children: [ 469 children: [
444 - TextSpan(text: text),  
445 - if (linkText case final linkText?)  
446 - TextSpan(text: linkText, style: _linkStyle),  
447 - if (linkSuffix case final linkSuffix?) TextSpan(text: linkSuffix), 470 + TextSpan(text: widget.text),
  471 + if (widget.linkText case final linkText?)
  472 + TextSpan(
  473 + text: linkText,
  474 + style: _linkStyle,
  475 + recognizer: widget.onLinkTap == null ? null : _linkRecognizer,
  476 + ),
  477 + if (widget.linkSuffix case final linkSuffix?)
  478 + TextSpan(text: linkSuffix),
448 ], 479 ],
449 ); 480 );
450 481
451 - void _handleTapUp(  
452 - BuildContext context,  
453 - BoxConstraints constraints,  
454 - TapUpDetails details,  
455 - ) {  
456 - final linkText = this.linkText;  
457 - if (linkText == null || onLinkTap == null) return;  
458 -  
459 - final painter = TextPainter(  
460 - text: _buildTextSpan(),  
461 - textDirection: Directionality.of(context),  
462 - textScaler: MediaQuery.textScalerOf(context),  
463 - )..layout(maxWidth: constraints.maxWidth);  
464 - final linkStart = text.length;  
465 - final linkBoxes = painter.getBoxesForSelection(  
466 - TextSelection(  
467 - baseOffset: linkStart,  
468 - extentOffset: linkStart + linkText.length,  
469 - ),  
470 - );  
471 -  
472 - if (linkBoxes.any(  
473 - (box) => box.toRect().inflate(10).contains(details.localPosition),  
474 - )) {  
475 - onLinkTap!.call();  
476 - }  
477 - }  
478 -  
479 @override 482 @override
480 Widget build(BuildContext context) { 483 Widget build(BuildContext context) {
481 return Row( 484 return Row(
482 crossAxisAlignment: CrossAxisAlignment.start, 485 crossAxisAlignment: CrossAxisAlignment.start,
483 children: [ 486 children: [
484 Text( 487 Text(
485 - prefix, 488 + widget.prefix,
486 style: const TextStyle( 489 style: const TextStyle(
487 color: PurchaseColors.subtitle, 490 color: PurchaseColors.subtitle,
488 fontSize: 12, 491 fontSize: 12,
@@ -490,17 +493,9 @@ class _LegalText extends StatelessWidget { @@ -490,17 +493,9 @@ class _LegalText extends StatelessWidget {
490 ), 493 ),
491 ), 494 ),
492 Expanded( 495 Expanded(
493 - child: LayoutBuilder(  
494 - builder: (context, constraints) => GestureDetector(  
495 - behavior: HitTestBehavior.opaque,  
496 - onTapUp: linkText == null || onLinkTap == null  
497 - ? null  
498 - : (details) => _handleTapUp(context, constraints, details),  
499 - child: Text.rich(  
500 - _buildTextSpan(),  
501 - textScaler: MediaQuery.textScalerOf(context),  
502 - ),  
503 - ), 496 + child: Text.rich(
  497 + _buildTextSpan(),
  498 + textScaler: MediaQuery.textScalerOf(context),
504 ), 499 ),
505 ), 500 ),
506 ], 501 ],
1 import 'dart:async'; 1 import 'dart:async';
2 2
  3 +import 'package:doublefeel_flutter/app/modules/login/views/email_login_contact_us_bottom_sheet.dart';
3 import 'package:doublefeel_flutter/app/routes/app_pages.dart'; 4 import 'package:doublefeel_flutter/app/routes/app_pages.dart';
4 import 'package:doublefeel_flutter/core/config/app_environment_config.dart'; 5 import 'package:doublefeel_flutter/core/config/app_environment_config.dart';
5 import 'package:doublefeel_flutter/core/constants/app_const.dart'; 6 import 'package:doublefeel_flutter/core/constants/app_const.dart';
@@ -394,7 +395,7 @@ class PurchaseController extends GetxController { @@ -394,7 +395,7 @@ class PurchaseController extends GetxController {
394 395
395 void openContactUs() { 396 void openContactUs() {
396 _trackClickVipCenter('联系我们'); 397 _trackClickVipCenter('联系我们');
397 - Get.toNamed(Routes.SUBMIT_FEEDBACK); 398 + feedbackCompat(pageName: 'Subscription page');
398 } 399 }
399 400
400 void openUserTerms() { 401 void openUserTerms() {
@@ -3,6 +3,7 @@ import 'package:doublefeel_flutter/app/widget/premium_benefit_list_view.dart'; @@ -3,6 +3,7 @@ import 'package:doublefeel_flutter/app/widget/premium_benefit_list_view.dart';
3 import 'package:doublefeel_flutter/core/util/size_extensions.dart'; 3 import 'package:doublefeel_flutter/core/util/size_extensions.dart';
4 import 'package:doublefeel_flutter/l10n/l10n_extensions.dart'; 4 import 'package:doublefeel_flutter/l10n/l10n_extensions.dart';
5 import 'package:doublefeel_flutter/r.dart'; 5 import 'package:doublefeel_flutter/r.dart';
  6 +import 'package:flutter/gestures.dart';
6 import 'package:flutter/material.dart'; 7 import 'package:flutter/material.dart';
7 import 'package:flutter/services.dart'; 8 import 'package:flutter/services.dart';
8 import 'package:get/get.dart'; 9 import 'package:get/get.dart';
@@ -287,7 +288,7 @@ class _LegalNotes extends StatelessWidget { @@ -287,7 +288,7 @@ class _LegalNotes extends StatelessWidget {
287 } 288 }
288 } 289 }
289 290
290 -class _LegalText extends StatelessWidget { 291 +class _LegalText extends StatefulWidget {
291 const _LegalText({ 292 const _LegalText({
292 required this.prefix, 293 required this.prefix,
293 required this.text, 294 required this.text,
@@ -302,6 +303,31 @@ class _LegalText extends StatelessWidget { @@ -302,6 +303,31 @@ class _LegalText extends StatelessWidget {
302 final String? linkSuffix; 303 final String? linkSuffix;
303 final VoidCallback? onLinkTap; 304 final VoidCallback? onLinkTap;
304 305
  306 + @override
  307 + State<_LegalText> createState() => _LegalTextState();
  308 +}
  309 +
  310 +class _LegalTextState extends State<_LegalText> {
  311 + late final TapGestureRecognizer _linkRecognizer;
  312 +
  313 + @override
  314 + void initState() {
  315 + super.initState();
  316 + _linkRecognizer = TapGestureRecognizer()..onTap = widget.onLinkTap;
  317 + }
  318 +
  319 + @override
  320 + void didUpdateWidget(covariant _LegalText oldWidget) {
  321 + super.didUpdateWidget(oldWidget);
  322 + _linkRecognizer.onTap = widget.onLinkTap;
  323 + }
  324 +
  325 + @override
  326 + void dispose() {
  327 + _linkRecognizer.dispose();
  328 + super.dispose();
  329 + }
  330 +
305 static const _baseStyle = TextStyle( 331 static const _baseStyle = TextStyle(
306 color: PurchaseColors.subtitle, 332 color: PurchaseColors.subtitle,
307 fontSize: 12, 333 fontSize: 12,
@@ -318,48 +344,25 @@ class _LegalText extends StatelessWidget { @@ -318,48 +344,25 @@ class _LegalText extends StatelessWidget {
318 TextSpan _buildTextSpan() => TextSpan( 344 TextSpan _buildTextSpan() => TextSpan(
319 style: _baseStyle, 345 style: _baseStyle,
320 children: [ 346 children: [
321 - TextSpan(text: text),  
322 - if (linkText case final linkText?)  
323 - TextSpan(text: linkText, style: _linkStyle),  
324 - if (linkSuffix case final linkSuffix?) TextSpan(text: linkSuffix), 347 + TextSpan(text: widget.text),
  348 + if (widget.linkText case final linkText?)
  349 + TextSpan(
  350 + text: linkText,
  351 + style: _linkStyle,
  352 + recognizer: widget.onLinkTap == null ? null : _linkRecognizer,
  353 + ),
  354 + if (widget.linkSuffix case final linkSuffix?)
  355 + TextSpan(text: linkSuffix),
325 ], 356 ],
326 ); 357 );
327 358
328 - void _handleTapUp(  
329 - BuildContext context,  
330 - BoxConstraints constraints,  
331 - TapUpDetails details,  
332 - ) {  
333 - final linkText = this.linkText;  
334 - if (linkText == null || onLinkTap == null) return;  
335 -  
336 - final painter = TextPainter(  
337 - text: _buildTextSpan(),  
338 - textDirection: Directionality.of(context),  
339 - textScaler: MediaQuery.textScalerOf(context),  
340 - )..layout(maxWidth: constraints.maxWidth);  
341 - final linkStart = text.length;  
342 - final linkBoxes = painter.getBoxesForSelection(  
343 - TextSelection(  
344 - baseOffset: linkStart,  
345 - extentOffset: linkStart + linkText.length,  
346 - ),  
347 - );  
348 -  
349 - if (linkBoxes.any(  
350 - (box) => box.toRect().inflate(10).contains(details.localPosition),  
351 - )) {  
352 - onLinkTap!.call();  
353 - }  
354 - }  
355 -  
356 @override 359 @override
357 Widget build(BuildContext context) { 360 Widget build(BuildContext context) {
358 return Row( 361 return Row(
359 crossAxisAlignment: CrossAxisAlignment.start, 362 crossAxisAlignment: CrossAxisAlignment.start,
360 children: [ 363 children: [
361 Text( 364 Text(
362 - prefix, 365 + widget.prefix,
363 style: const TextStyle( 366 style: const TextStyle(
364 color: PurchaseColors.subtitle, 367 color: PurchaseColors.subtitle,
365 fontSize: 12, 368 fontSize: 12,
@@ -367,17 +370,9 @@ class _LegalText extends StatelessWidget { @@ -367,17 +370,9 @@ class _LegalText extends StatelessWidget {
367 ), 370 ),
368 ), 371 ),
369 Expanded( 372 Expanded(
370 - child: LayoutBuilder(  
371 - builder: (context, constraints) => GestureDetector(  
372 - behavior: HitTestBehavior.opaque,  
373 - onTapUp: linkText == null || onLinkTap == null  
374 - ? null  
375 - : (details) => _handleTapUp(context, constraints, details),  
376 - child: Text.rich(  
377 - _buildTextSpan(),  
378 - textScaler: MediaQuery.textScalerOf(context),  
379 - ),  
380 - ), 373 + child: Text.rich(
  374 + _buildTextSpan(),
  375 + textScaler: MediaQuery.textScalerOf(context),
381 ), 376 ),
382 ), 377 ),
383 ], 378 ],
@@ -666,7 +666,7 @@ @@ -666,7 +666,7 @@
666 "premiumActivatedContinue": "Continue", 666 "premiumActivatedContinue": "Continue",
667 "purchaseHeroTitle": "Unlock Pro, Care Better", 667 "purchaseHeroTitle": "Unlock Pro, Care Better",
668 "purchaseBenefitsTitle": "Unlock All Pro Benefits", 668 "purchaseBenefitsTitle": "Unlock All Pro Benefits",
669 - "purchaseUnlockNow": "Unlock", 669 + "purchaseUnlockNow": "Next",
670 "purchaseRestore": "Restore", 670 "purchaseRestore": "Restore",
671 "purchaseTermsOfService": "Terms of Service", 671 "purchaseTermsOfService": "Terms of Service",
672 "purchasePrivacyPolicy": "Privacy Policy", 672 "purchasePrivacyPolicy": "Privacy Policy",
@@ -1065,4 +1065,4 @@ @@ -1065,4 +1065,4 @@
1065 } 1065 }
1066 }, 1066 },
1067 "updatePassword": "Update password" 1067 "updatePassword": "Update password"
1068 -}  
  1068 +}
@@ -1926,7 +1926,7 @@ class AppLocalizationsEn extends AppLocalizations { @@ -1926,7 +1926,7 @@ class AppLocalizationsEn extends AppLocalizations {
1926 String get purchaseBenefitsTitle => 'Unlock All Pro Benefits'; 1926 String get purchaseBenefitsTitle => 'Unlock All Pro Benefits';
1927 1927
1928 @override 1928 @override
1929 - String get purchaseUnlockNow => 'Unlock'; 1929 + String get purchaseUnlockNow => 'Next';
1930 1930
1931 @override 1931 @override
1932 String get purchaseRestore => 'Restore'; 1932 String get purchaseRestore => 'Restore';