diff --git a/app/CONTRIBUTING.md b/app/CONTRIBUTING.md index 1c47088e..239dfb14 100644 --- a/app/CONTRIBUTING.md +++ b/app/CONTRIBUTING.md @@ -132,3 +132,20 @@ needs to be adapted (see [[IntegrationTestPlugin instance] setupChannels:registrar.messenger]; } ``` + +## Adapting test data + +If you would like to test with specific test data but you don't have a user with +suitable data available, adapt the code in `utilities/genome_data.dart` as +shown below. + +```dart +// TODO(after-testing): remove test data adaption +UserData.instance.diplotypes!['CYP2D6'] = Diplotype( + gene: 'CYP2D6', + resultType: 'Diplotype', + genotype: '*18/*143', + phenotype: 'Poor Metabolizer', + allelesTested: '*xN.*3.*4.*5.*6.*8.*9.*10.*14A.*14B.*17.*18.*41.*143', +); +``` diff --git a/app/lib/common/models/drug/drug_inhibitors.dart b/app/lib/common/models/drug/drug_inhibitors.dart index 343b3766..f089f42a 100644 --- a/app/lib/common/models/drug/drug_inhibitors.dart +++ b/app/lib/common/models/drug/drug_inhibitors.dart @@ -5,9 +5,7 @@ // structure: gene symbol -> drug name -> overwriting lookupkey -import 'package:dartx/dartx.dart'; - -import 'drug.dart'; +import '../../module.dart'; // Inhibit phenotype for gene by overwriting with poor metabolizer const Map> strongDrugInhibitors = { @@ -63,9 +61,16 @@ bool isModerateInhibitor(String drugName) { } bool isInhibitor(String drugName) { - final influencingDrugs = _drugInhibitorsPerGene.keys.flatMap( - (gene) => _drugInhibitorsPerGene[gene]!); - return influencingDrugs.contains(drugName); + var drugIsInhibitor = false; + for (final geneSymbol in _drugInhibitorsPerGene.keys) { + final influencingDrugs = _drugInhibitorsPerGene[geneSymbol]; + final originalLookup = UserData.lookupFor(geneSymbol, drug: drugName, useOverwrite: false); + if (influencingDrugs!.contains(drugName) && originalLookup != '0.0') { + drugIsInhibitor = true; + break; + } + } + return drugIsInhibitor; } List inhibitedGenes(Drug drug) { @@ -77,3 +82,8 @@ List inhibitedGenes(Drug drug) { List inhibitorsFor(String geneSymbol) { return _drugInhibitorsPerGene[geneSymbol] ?? []; } + +bool canBeInhibited(CpicPhenotype phenotype) { + return inhibitableGenes.contains(phenotype.geneSymbol) && + phenotype.lookupkey != '0.0'; +} diff --git a/app/lib/common/models/userdata/userdata.dart b/app/lib/common/models/userdata/userdata.dart index 4bfd8033..3846c3bf 100644 --- a/app/lib/common/models/userdata/userdata.dart +++ b/app/lib/common/models/userdata/userdata.dart @@ -15,12 +15,12 @@ class PhenotypeInformation { PhenotypeInformation({ required this.phenotype, this.adaptionText, - this.overwrittenPhenotype, + this.overwrittenPhenotypeText, }); String phenotype; String? adaptionText; - String? overwrittenPhenotype; + String? overwrittenPhenotypeText; } /// UserData is a singleton data-class which contains various user-specific @@ -48,14 +48,21 @@ class UserData { @HiveField(0) Map? diplotypes; - static PhenotypeInformation phenotypeFor( + static PhenotypeInformation phenotypeInformationFor( String gene, BuildContext context, { String? drug, - String userSalutation = 'you', + bool thirdPerson = false, + bool useLongPrefix = false, } ) { + final userSalutation = thirdPerson + ? context.l10n.drugs_page_inhibitor_third_person_salutation + : context.l10n.drugs_page_inhibitor_direct_salutation; + final strongInhibitorTextPrefix = useLongPrefix + ? context.l10n.strong_inhibitor_long_prefix + : context.l10n.gene_page_phenotype.toLowerCase(); final originalPhenotype = UserData.instance.diplotypes?[gene]?.phenotype; if (originalPhenotype == null) { return PhenotypeInformation( @@ -66,32 +73,19 @@ class UserData { if (activeInhibitors.isEmpty) { return PhenotypeInformation(phenotype: originalPhenotype); } - final overwrittenLookup = UserData.overwrittenLookup(gene, drug: drug); - if (overwrittenLookup == null) { - return PhenotypeInformation( - phenotype: originalPhenotype, - adaptionText: context.l10n.drugs_page_moderate_inhibitors( - userSalutation, - enumerationWithAnd( - activeInhibitors, - context - ), - ), - ); - } - final activeStrongInhibitors = activeInhibitors.filter( - isStrongInhibitor - ).toList(); - final activeModerateInhibitors = activeInhibitors.filter( - isModerateInhibitor - ).toList(); final overwritePhenotype = context.l10n.general_poor_metabolizer; final currentPhenotypeEqualsOverwritePhenotype = originalPhenotype.toLowerCase() == overwritePhenotype.toLowerCase(); if (currentPhenotypeEqualsOverwritePhenotype) { return PhenotypeInformation( phenotype: originalPhenotype, - adaptionText: context.l10n.drugs_page_inhibitors_poor_metabolizer( + ); + } + final overwrittenLookup = UserData.overwrittenLookup(gene, drug: drug); + if (overwrittenLookup == null) { + return PhenotypeInformation( + phenotype: originalPhenotype, + adaptionText: context.l10n.drugs_page_moderate_inhibitors( userSalutation, enumerationWithAnd( activeInhibitors, @@ -100,20 +94,20 @@ class UserData { ), ); } - final adaptionText = activeModerateInhibitors.isEmpty - ? context.l10n.drugs_page_strong_inhibitors( - userSalutation, - enumerationWithAnd(activeStrongInhibitors, context), - ) - : context.l10n.drugs_page_moderate_and_strong_inhibitors( - userSalutation, - enumerationWithAnd(activeStrongInhibitors, context), - enumerationWithAnd(activeModerateInhibitors, context), - ); + final originalPhenotypeText = context.l10n.drugs_page_original_phenotype( + thirdPerson + ? context.l10n.drugs_page_inhibitor_third_person_salutation_genitive + : context.l10n.drugs_page_inhibitor_direct_salutation_genitive, + originalPhenotype, + ); return PhenotypeInformation( phenotype: overwritePhenotype, - adaptionText: adaptionText, - overwrittenPhenotype: originalPhenotype, + adaptionText: context.l10n.drugs_page_strong_inhibitors( + strongInhibitorTextPrefix, + userSalutation, + enumerationWithAnd(activeInhibitors, context), + ), + overwrittenPhenotypeText: originalPhenotypeText, ); } diff --git a/app/lib/common/utilities/pdf_utils.dart b/app/lib/common/utilities/pdf_utils.dart index 750a8449..501b32e8 100644 --- a/app/lib/common/utilities/pdf_utils.dart +++ b/app/lib/common/utilities/pdf_utils.dart @@ -125,22 +125,21 @@ List _buildDrugPart(Drug drug, BuildContext buildContext) { } String? _getPhenotypeInfo(String gene, Drug drug, BuildContext context) { - final phenotypeInformation = UserData.phenotypeFor( + final phenotypeInformation = UserData.phenotypeInformationFor( gene, context, drug: drug.name, - userSalutation: context.l10n.general_the_user, + thirdPerson: true, + useLongPrefix: true, ); if (phenotypeInformation.adaptionText.isNullOrBlank) { return phenotypeInformation.phenotype; } var phenotypeInformationText = '${phenotypeInformation.phenotype} (' '${phenotypeInformation.adaptionText}'; - if (phenotypeInformation.overwrittenPhenotype.isNotNullOrBlank) { + if (phenotypeInformation.overwrittenPhenotypeText.isNotNullOrBlank) { phenotypeInformationText = '$phenotypeInformationText; ' - '${context.l10n.drugs_page_original_phenotype( - phenotypeInformation.overwrittenPhenotype! - )}'; + '${phenotypeInformation.overwrittenPhenotypeText!}'; } return '$phenotypeInformationText)'; } diff --git a/app/lib/drug/widgets/annotation_cards/annotation_table.dart b/app/lib/common/widgets/annotation_table.dart similarity index 77% rename from app/lib/drug/widgets/annotation_cards/annotation_table.dart rename to app/lib/common/widgets/annotation_table.dart index 82835f7f..6121b947 100644 --- a/app/lib/drug/widgets/annotation_cards/annotation_table.dart +++ b/app/lib/common/widgets/annotation_table.dart @@ -1,4 +1,4 @@ -import '../../../common/module.dart'; +import '../module.dart'; class TableRowDefinition { const TableRowDefinition(this.key, this.value); @@ -10,6 +10,7 @@ Table buildTable( List rowDefinitions, { TextStyle? style, + bool boldHeader = true, } ) { return Table( @@ -18,6 +19,7 @@ Table buildTable( rowDefinition.key, rowDefinition.value, style ?? PharMeTheme.textTheme.bodyMedium!, + boldHeader: boldHeader, )).toList(), ); } @@ -26,6 +28,7 @@ TableRow _buildRow( String key, String value, TextStyle textStyle, + { required bool boldHeader } ) { return TableRow( children: [ @@ -33,7 +36,9 @@ TableRow _buildRow( padding: EdgeInsets.only(right: PharMeTheme.smallSpace), child: Text( key, - style: textStyle.copyWith(fontWeight: FontWeight.bold), + style: boldHeader + ? textStyle.copyWith(fontWeight: FontWeight.bold) + : textStyle, ), ), Text(value, style: textStyle), diff --git a/app/lib/common/widgets/drug_search.dart b/app/lib/common/widgets/drug_search.dart index cc14c956..fe039e1c 100644 --- a/app/lib/common/widgets/drug_search.dart +++ b/app/lib/common/widgets/drug_search.dart @@ -64,14 +64,6 @@ class DrugSearch extends HookWidget { if (showFilter) buildFilter(context), ] ), - SizedBox(height: PharMeTheme.smallSpace), - if (showDrugInteractionIndicator) - PageIndicatorExplanation( - context.l10n.search_page_indicator_explanation( - drugInteractionIndicatorName, - drugInteractionIndicator - ), - ), scrollList( keepPosition: keepPosition, buildDrugList( @@ -86,6 +78,18 @@ class DrugSearch extends HookWidget { useDrugClass: useDrugClass, ) ), + state.when( + initial: SizedBox.shrink, + loading: SizedBox.shrink, + loaded: (allDrugs, filter) => + maybeBuildInteractionIndicator( + context, + activeDrugs, + allDrugs, + filter, + ), + error: SizedBox.shrink, + ) ], ); } @@ -132,4 +136,27 @@ class DrugSearch extends HookWidget { iconData: Icons.filter_list_rounded, ); } + Widget maybeBuildInteractionIndicator( + BuildContext context, + ActiveDrugs activeDrugs, + List drugs, + FilterState filter, + ) { + if (showDrugInteractionIndicator) { + final filteredDrugs = filter.filter( + drugs, + activeDrugs, + useDrugClass: useDrugClass, + ); + if (filteredDrugs.any((drug) => isInhibitor(drug.name))) { + return PageIndicatorExplanation( + context.l10n.search_page_indicator_explanation( + drugInteractionIndicatorName, + drugInteractionIndicator + ), + ); + } + } + return SizedBox.shrink(); + } } diff --git a/app/lib/common/widgets/error_handler.dart b/app/lib/common/widgets/error_handler.dart index 4dc1c15d..2b15cf42 100644 --- a/app/lib/common/widgets/error_handler.dart +++ b/app/lib/common/widgets/error_handler.dart @@ -1,3 +1,5 @@ +import 'package:flutter/foundation.dart'; + import '../module.dart'; class ErrorHandler extends StatefulWidget { @@ -34,6 +36,9 @@ class ErrorHandlerState extends State { }) async { debugPrint(exception.toString()); debugPrintStack(stackTrace: stackTrace); + if (kDebugMode) { + if (exception is AssertionError) return; + } final errorString = exception.toString(); if (_needToHandleError(exception)) { final errorMailInfo = stackTrace != null diff --git a/app/lib/common/widgets/module.dart b/app/lib/common/widgets/module.dart index ceeaccf1..72022b52 100644 --- a/app/lib/common/widgets/module.dart +++ b/app/lib/common/widgets/module.dart @@ -1,3 +1,4 @@ +export 'annotation_table.dart'; export 'checkbox_list_tile_wrapper.dart'; export 'checkbox_wrapper.dart'; export 'dialog_action.dart'; diff --git a/app/lib/common/widgets/page_indicator_explanation.dart b/app/lib/common/widgets/page_indicator_explanation.dart index 52278887..acde779f 100644 --- a/app/lib/common/widgets/page_indicator_explanation.dart +++ b/app/lib/common/widgets/page_indicator_explanation.dart @@ -8,11 +8,7 @@ class PageIndicatorExplanation extends StatelessWidget { @override Widget build(BuildContext context) { return Padding( - padding: EdgeInsets.only( - left: PharMeTheme.smallSpace, - right: PharMeTheme.smallSpace, - bottom: PharMeTheme.smallSpace, - ), + padding: EdgeInsets.all(PharMeTheme.smallSpace), child: Text(text), ); } diff --git a/app/lib/common/widgets/page_scaffold.dart b/app/lib/common/widgets/page_scaffold.dart index d01d2b01..3c358a36 100644 --- a/app/lib/common/widgets/page_scaffold.dart +++ b/app/lib/common/widgets/page_scaffold.dart @@ -80,7 +80,11 @@ Scaffold unscrollablePageScaffold({ appBar: appBar, body: SafeArea( child: Padding( - padding: EdgeInsets.all(padding ?? PharMeTheme.smallSpace), + padding: EdgeInsets.only( + left: padding ?? PharMeTheme.smallSpace, + top: padding ?? PharMeTheme.smallSpace, + right: padding ?? PharMeTheme.smallSpace, + ), child: body, ), ), diff --git a/app/lib/common/widgets/scroll_list.dart b/app/lib/common/widgets/scroll_list.dart index d96425a0..f9ba25bf 100644 --- a/app/lib/common/widgets/scroll_list.dart +++ b/app/lib/common/widgets/scroll_list.dart @@ -2,10 +2,7 @@ import 'package:flutter_list_view/flutter_list_view.dart'; import '../module.dart'; -Widget scrollList(List body, { - bool keepPosition = false, - double? verticalPadding, -}) { +Widget scrollList(List body, { bool keepPosition = false }) { String getItemKey(Widget widget) => widget.key.toString(); if (body.map(getItemKey).toSet().length != body.length) { throw Exception('Items passed to scrollList need unique keys'); @@ -18,21 +15,7 @@ Widget scrollList(List body, { padding: EdgeInsets.only(right: PharMeTheme.mediumSpace), child: FlutterListView( delegate: FlutterListViewDelegate( - (context, index) => (index == 0) - ? Padding( - padding: EdgeInsets.only( - top: verticalPadding ?? PharMeTheme.smallSpace, - ), - child: body[index] - ) - : (index == body.length - 1) - ? Padding( - padding: EdgeInsets.only( - bottom: verticalPadding ?? PharMeTheme.smallSpace, - ), - child: body[index] - ) - : body[index], + (context, index) => body[index], childCount: body.length, onItemKey: (index) => getItemKey(body[index]), keepPosition: keepPosition, diff --git a/app/lib/drug/pages/drug.dart b/app/lib/drug/pages/drug.dart index 19ce5665..4e83e6d3 100644 --- a/app/lib/drug/pages/drug.dart +++ b/app/lib/drug/pages/drug.dart @@ -33,7 +33,9 @@ class DrugPage extends StatelessWidget { Widget _buildDrugsPage(BuildContext context, { required bool loading }) { return pageScaffold( - title: drug.name.capitalize(), + title: isInhibitor(drug.name) + ? '${drug.name.capitalize()}$drugInteractionIndicator' + : drug.name.capitalize(), actions: [ IconButton( onPressed: loading ? null : () => diff --git a/app/lib/drug/widgets/annotation_cards/drug.dart b/app/lib/drug/widgets/annotation_cards/drug.dart index 6dfbac36..a8307ea6 100644 --- a/app/lib/drug/widgets/annotation_cards/drug.dart +++ b/app/lib/drug/widgets/annotation_cards/drug.dart @@ -1,6 +1,5 @@ import '../../../common/module.dart'; import '../sub_header.dart'; -import 'annotation_table.dart'; class DrugAnnotationCard extends StatelessWidget { const DrugAnnotationCard( @@ -42,10 +41,16 @@ class DrugAnnotationCard extends StatelessWidget { ]), if (isInhibitor(drug.name)) ...[ SizedBox(height: 8), - Text(context.l10n.drugs_page_is_inhibitor( - drug.name, - inhibitedGenes(drug).join(', '), - )), + buildTable( + [TableRowDefinition( + drugInteractionIndicator, + context.l10n.drugs_page_is_inhibitor( + drug.name, + inhibitedGenes(drug).join(', '), + ), + )], + boldHeader: false, + ), ], ], ), diff --git a/app/lib/drug/widgets/annotation_cards/guideline.dart b/app/lib/drug/widgets/annotation_cards/guideline.dart index c2a5d369..e6f8ce9b 100644 --- a/app/lib/drug/widgets/annotation_cards/guideline.dart +++ b/app/lib/drug/widgets/annotation_cards/guideline.dart @@ -85,7 +85,7 @@ class GuidelineAnnotationCard extends StatelessWidget { final genes = drug.userGuideline?.lookupkey.keys ?? drug.guidelines.first.lookupkey.keys; final geneDescriptions = genes.map((geneSymbol) { - final phenotypeInformation = UserData.phenotypeFor( + final phenotypeInformation = UserData.phenotypeInformationFor( geneSymbol, context, drug: drug.name, diff --git a/app/lib/drug/widgets/module.dart b/app/lib/drug/widgets/module.dart index c79aef87..d3c94d6e 100644 --- a/app/lib/drug/widgets/module.dart +++ b/app/lib/drug/widgets/module.dart @@ -1,4 +1,3 @@ -export 'annotation_cards/annotation_table.dart'; export 'annotation_cards/disclaimer.dart'; export 'annotation_cards/drug.dart'; export 'annotation_cards/guideline.dart'; diff --git a/app/lib/drug_selection/pages/drug_selection.dart b/app/lib/drug_selection/pages/drug_selection.dart index a7c64f40..328ab0e2 100644 --- a/app/lib/drug_selection/pages/drug_selection.dart +++ b/app/lib/drug_selection/pages/drug_selection.dart @@ -52,11 +52,7 @@ class DrugSelectionPage extends HookWidget { Widget _buildButton(BuildContext context, DrugSelectionState state) { return Padding( - padding: EdgeInsets.only( - left: PharMeTheme.mediumSpace, - top: PharMeTheme.mediumSpace, - right: PharMeTheme.mediumSpace, - ), + padding: EdgeInsets.all(PharMeTheme.mediumSpace), child: FullWidthButton( context.l10n.action_continue, () async { diff --git a/app/lib/error/pages/error.dart b/app/lib/error/pages/error.dart index 18bf3655..df976e64 100644 --- a/app/lib/error/pages/error.dart +++ b/app/lib/error/pages/error.dart @@ -62,6 +62,7 @@ class ErrorPage extends StatelessWidget { () => exit(0), secondaryColor: true, ), + SizedBox(height: PharMeTheme.mediumSpace), ], ), ), diff --git a/app/lib/l10n/app_en.arb b/app/lib/l10n/app_en.arb index 1e97010f..7050143e 100644 --- a/app/lib/l10n/app_en.arb +++ b/app/lib/l10n/app_en.arb @@ -48,7 +48,6 @@ "general_retry": "Retry", "general_and": "and", "general_poor_metabolizer": "Poor Metabolizer", - "general_the_user": "the user", "general_not_tested": "Not tested", "search_page_tooltip_search": "Search for drugs by their name, brand name or class.", @@ -60,7 +59,6 @@ "search_page_filter_only_with_guidelines": "Only drugs with guidelines", "search_page_indicator_explanation": "Taking drugs with an {indicatorName} ({indicator}) can influence your results for other drugs", "@search_page_indicator_explanation": { - "description": "Explanation of drug-drug interaction indicators", "placeholders": { "indicatorName": { "type": "String", @@ -75,7 +73,6 @@ "search_no_drugs_with_filter_amendment": " or filters right to the search bar", "search_no_drugs": "No drugs found. Try adjusting the search term{amendment}.", "@search_no_drugs": { - "description": "Disclaimer for when no drug was found in the search", "placeholders": { "amendment": { "type": "String", @@ -86,7 +83,6 @@ "drugs_page_disclaimer": "Please note the information shown on this page is ONLY based on your DNA and relevant current medications. Other important factors like weight, age, pre-existing conditions, and drug interactions are not considered.", "drugs_page_is_inhibitor": "Taking {drugName} can influence your results for the following gene(s): {geneSymbols}", "@drugs_page_is_inhibitor": { - "description": "Disclaimer for when the current drug influences other guidelines", "placeholders": { "drugName": { "type": "String", @@ -99,13 +95,16 @@ } }, - "drugs_page_moderate_inhibitors": "however, the phenotype can be influenced based on {salutation} taking {inhibitors}", + "drugs_page_inhibitor_direct_salutation": "you are", + "drugs_page_inhibitor_direct_salutation_genitive": "your", + "drugs_page_inhibitor_third_person_salutation": "the user is", + "drugs_page_inhibitor_third_person_salutation_genitive": "the user's", + "drugs_page_moderate_inhibitors": "this phenotype may need to be adjusted because {salutation} currently taking {inhibitors}", "@drugs_page_moderate_inhibitors": { - "description": "Disclaimer for when the phenotype might be adjusted based on current drug(s)", "placeholders": { "salutation": { "type": "String", - "example": "you" + "example": "you are" }, "inhibitors": { "type": "String", @@ -113,27 +112,17 @@ } } }, - "drugs_page_strong_inhibitors": "phenotype adjusted based on {salutation} taking {inhibitors}", + "strong_inhibitor_long_prefix": "however, this has been", + "drugs_page_strong_inhibitors": "{prefix} adjusted because {salutation} currently taking {inhibitors}", "@drugs_page_strong_inhibitors": { - "description": "Disclaimer for when the phenotype has been adjusted based on current drug(s)", "placeholders": { - "salutation": { + "prefix": { "type": "String", - "example": "you" + "example": "phenotype" }, - "inhibitors": { - "type": "String", - "example": "bupropion and fluoxetine" - } - } - }, - "drugs_page_inhibitors_poor_metabolizer": "this can be further influenced based on {salutation} taking {inhibitors}", - "@drugs_page_inhibitors_poor_metabolizer": { - "description": "Disclaimer for when the phenotype would be adjusted based on current drug(s) but is already poor metabolizer", - "placeholders": { "salutation": { "type": "String", - "example": "you" + "example": "you are" }, "inhibitors": { "type": "String", @@ -141,28 +130,13 @@ } } }, - "drugs_page_moderate_and_strong_inhibitors": "phenotype adjusted based on {salutation} taking {strongInhibitors}; this can be further influenced by {moderateInhibitors}", - "@drugs_page_moderate_and_strong_inhibitors": { - "description": "Disclaimer for when the phenotype has been and might be adjusted based on current drug(s)", + "drugs_page_original_phenotype": "{salutation} DNA-based phenotype is {originalPhenotype}", + "@drugs_page_original_phenotype": { "placeholders": { "salutation": { "type": "String", - "example": "you" + "example": "your" }, - "strongInhibitors": { - "type": "String", - "example": "bupropion" - }, - "moderateInhibitors": { - "type": "String", - "example": "abiraterone, cinacalcet, and duloxetine" - } - } - }, - "drugs_page_original_phenotype": "the DNA-based phenotype is {originalPhenotype}", - "@drugs_page_original_phenotype": { - "description": "Information on DNA-based phenotype if it was/might be adjusted based on current drug(s)", - "placeholders": { "originalPhenotype": { "type": "String", "example": "Normal Metabolizer" @@ -171,7 +145,6 @@ }, "drugs_page_guidelines_empty": "No guidelines are present for {drugName}", "@drugs_page_guidelines_empty": { - "description": "Disclaimer when a drug does not have guidelines", "placeholders": { "drugName": { "type": "String", @@ -190,7 +163,6 @@ "drugs_page_header_guideline": "DNA-based clinical guideline", "drugs_page_no_guidelines_for_phenotype_implication": "More information is needed to comment on your DNA's influence on {drugName}.", "@drugs_page_no_guidelines_for_phenotype_implication": { - "description": "Disclaimer for when no guidelines was found for the current drug based on the user's phenotype", "placeholders": { "drugName": { "type": "String", @@ -201,7 +173,6 @@ "drugs_page_no_guidelines_for_phenotype_recommendation": "Clinical dosing applies; no pharmacogenetic recommendation can be made at this time. Consult your pharmacist or doctor for more information.", "drugs_page_sources_description": "Tap here to review the corresponding guideline published by {source}", "@drugs_page_sources_description": { - "description": "Instructions to open external source", "placeholders": { "source": { "type": "String", @@ -233,7 +204,6 @@ "report_content_explanation": "Here is your PGx report. Tap on a gene name for more details on your results and a list of implicated drugs.", "report_page_indicator_explanation": "Phenotypes followed by an {indicatorName} ({indicator}) might be influenced by drugs you are currently taking", "@report_page_indicator_explanation": { - "description": "Explanation of drug-drug interaction indicators", "placeholders": { "indicatorName": { "type": "String", @@ -248,7 +218,6 @@ "gene_page_headline": "{geneSymbol} report", "@gene_page_headline": { - "description": "Name of the gene", "placeholders": { "geneSymbol": { "type": "String", @@ -258,7 +227,6 @@ }, "gene_page_your_variant": "Your {geneSymbol} variant", "@gene_page_your_variant": { - "description": "Name of the variant", "placeholders": { "geneSymbol": { "type": "String", @@ -268,7 +236,6 @@ }, "gene_page_name_tooltip": "{geneSymbol} is the name of a gene.", "@gene_page_name_tooltip": { - "description": "Name of the gene (help text)", "placeholders": { "geneSymbol": { "type": "String", @@ -284,7 +251,7 @@ "gene_page_affected_drugs_tooltip": "The drugs listed here are influenced by your phenotype for this gene.", "gene_page_no_affected_drugs": "This gene has no known effect on any drug.", "gene_page_inhibitor_drugs": "Your results for this gene can be influenced if you are currently taking any of the following drugs:", - "gene_page_further_inhibitor_drugs": "Your results for this gene may need to be adjusted if you are currently taking any of the following drugs:", + "gene_page_further_inhibitor_drugs": "Your results for this gene can also be influenced by taking any of the following drugs:", "gene_page_activity_score": "Activity score", "pdf_pgx_report": "PGx Report", @@ -298,7 +265,6 @@ "pdf_user_guideline": "User guideline", "pdf_guideline_link": "{guidelineSource} guideline link", "@pdf_guideline_link": { - "description": "Source of the guideline", "placeholders": { "guidelineSource": { "type": "String", @@ -308,7 +274,6 @@ }, "pdf_guideline_recommmendation": "{guidelineSource} recommendation", "@pdf_guideline_recommmendation": { - "description": "Guideline recommendation of source", "placeholders": { "guidelineSource": { "type": "String", @@ -318,7 +283,6 @@ }, "pdf_guideline_gene_implication": "{guidelineSource} implication for {geneSymbol}", "@pdf_guideline_gene_implication": { - "description": "Guideline implication of source", "placeholders": { "guidelineSource": { "type": "String", @@ -332,7 +296,6 @@ }, "pdf_guideline_comment": "{guidelineSource} comment", "@pdf_guideline_comment": { - "description": "Guideline comment of source", "placeholders": { "guidelineSource": { "type": "String", @@ -342,7 +305,6 @@ }, "pdf_activity_score_overwrite": "{originalScore} adjusted based on active medications, see phenotype", "@pdf_activity_score_overwrite": { - "description": "Disclaimer for when the lookup has been or might be adjusted based on current drug(s)", "placeholders": { "originalScore": { "type": "String", diff --git a/app/lib/login/pages/login.dart b/app/lib/login/pages/login.dart index f5081e30..b0115364 100644 --- a/app/lib/login/pages/login.dart +++ b/app/lib/login/pages/login.dart @@ -27,7 +27,10 @@ class LoginPage extends HookWidget { child: state.when( initial: () => _buildInitialScreen(context, dropdownValue), - loadingUserData: CircularProgressIndicator.new, + loadingUserData: () => Padding( + padding: EdgeInsets.all(PharMeTheme.mediumSpace), + child: CircularProgressIndicator(), + ), loadedUserData: () => _buildLoadedScreen(context), error: (message) => _buildErrorScreen(context, message), @@ -153,6 +156,7 @@ class LoginPage extends HookWidget { ...children, SizedBox(height: PharMeTheme.mediumSpace), FullWidthButton(actionText, action ?? () {}), + SizedBox(height: PharMeTheme.mediumSpace), ], ); } diff --git a/app/lib/report/pages/gene.dart b/app/lib/report/pages/gene.dart index f42159fb..c4e59229 100644 --- a/app/lib/report/pages/gene.dart +++ b/app/lib/report/pages/gene.dart @@ -52,17 +52,10 @@ class GenePage extends HookWidget { phenotype.genotype, tooltip: context.l10n.gene_page_genotype_tooltip ), - _buildRow(context.l10n.gene_page_phenotype, - UserData.phenotypeFor( - phenotype.geneSymbol, - context, - ).phenotype, - tooltip: - context.l10n.gene_page_phenotype_tooltip - ), + _buildPhenotypeRow(context), ], ), - if (inhibitableGenes.contains(phenotype.geneSymbol)) + if (canBeInhibited(phenotype)) ...buildDrugInteractionInfo( context, phenotype.geneSymbol, @@ -85,6 +78,23 @@ class GenePage extends HookWidget { ); } + TableRow _buildPhenotypeRow(BuildContext context) { + final phenotypeInformation = UserData.phenotypeInformationFor( + phenotype.geneSymbol, + context, + ); + final phenotypeText = phenotypeInformation.adaptionText.isNotNullOrBlank + ? '${phenotypeInformation.phenotype}$drugInteractionIndicator' + : phenotypeInformation.phenotype; + if (phenotypeInformation.adaptionText.isNotNullOrBlank) {} + return _buildRow( + context.l10n.gene_page_phenotype, + phenotypeText, + tooltip: + context.l10n.gene_page_phenotype_tooltip, + ); + } + TableRow _buildRow(String key, String value, {String? tooltip}) => TableRow(children: [ Padding( @@ -107,23 +117,33 @@ class GenePage extends HookWidget { ]); List buildDrugInteractionInfo(BuildContext context, String gene) { - final phenotypeInformation = UserData.phenotypeFor(gene, context); + final phenotypeInformation = UserData.phenotypeInformationFor( + gene, + context, + useLongPrefix: true, + ); if (phenotypeInformation.adaptionText.isNotNullOrBlank) { final furtherInhibitors = inhibitorsFor(gene).filter((drugName) => !UserData.activeInhibitorsFor(gene).contains(drugName) ); - var phenotypeInformationText = formatAsSentence( - phenotypeInformation.adaptionText! - ); - if (phenotypeInformation.overwrittenPhenotype.isNotNullOrBlank) { - phenotypeInformationText = '$phenotypeInformationText ${ - formatAsSentence(context.l10n.drugs_page_original_phenotype( - phenotypeInformation.overwrittenPhenotype! - ))}'; + var phenotypeInformationText = ''; + if (phenotypeInformation.overwrittenPhenotypeText.isNotNullOrBlank) { + phenotypeInformationText = '${formatAsSentence( + phenotypeInformation.overwrittenPhenotypeText! + )} '; } + phenotypeInformationText = '$phenotypeInformationText${formatAsSentence( + phenotypeInformation.adaptionText! + )}'; return [ SizedBox(height: PharMeTheme.smallSpace), - Text(phenotypeInformationText), + buildTable( + [TableRowDefinition( + drugInteractionIndicator, + phenotypeInformationText, + )], + boldHeader: false, + ), SizedBox(height: PharMeTheme.smallSpace), Text(context.l10n.gene_page_further_inhibitor_drugs), SizedBox(height: PharMeTheme.smallSpace), diff --git a/app/lib/report/pages/report.dart b/app/lib/report/pages/report.dart index 9579f8e2..3b7a86d6 100644 --- a/app/lib/report/pages/report.dart +++ b/app/lib/report/pages/report.dart @@ -31,21 +31,18 @@ class ReportPage extends StatelessWidget { barBottom: context.l10n.report_content_explanation, body: Column( children: [ - if (hasActiveInhibitors) Padding( - padding: EdgeInsets.only(top: PharMeTheme.smallSpace), - child: PageIndicatorExplanation( - context.l10n.report_page_indicator_explanation( - drugInteractionIndicatorName, - drugInteractionIndicator - ), - ), - ), scrollList( userPhenotypes.map((phenotype) => GeneCard( phenotype, key: Key('gene-card-${phenotype.geneSymbol}') )).toList(), ), + if (hasActiveInhibitors) PageIndicatorExplanation( + context.l10n.report_page_indicator_explanation( + drugInteractionIndicatorName, + drugInteractionIndicator + ), + ), ] ) ), @@ -60,7 +57,7 @@ class GeneCard extends StatelessWidget { @override Widget build(BuildContext context) { - final phenotypeInformation = UserData.phenotypeFor( + final phenotypeInformation = UserData.phenotypeInformationFor( phenotype.geneSymbol, context, );