diff --git a/app/lib/common/utilities/drug_utils.dart b/app/lib/common/utilities/drug_utils.dart index e517193a..b9575783 100644 --- a/app/lib/common/utilities/drug_utils.dart +++ b/app/lib/common/utilities/drug_utils.dart @@ -4,6 +4,27 @@ import 'package:http/http.dart'; import '../../app.dart'; import '../module.dart'; +List getInhibitedGenotypesForDrug(Drug drug) { + final genotypeResults = getGenotypeResultsForDrug(drug); + return genotypeResults?.filter( + (genotypeResult) => isInhibited(genotypeResult, drug: drug.name) + ).toList() ?? []; +} + +List? getGenotypeResultsForDrug(Drug drug) { + if (drug.userGuideline == null && drug.guidelines.isEmpty) { + return null; + } + return drug.guidelineGenotypes.map((genotypeKey) => + UserData.instance.genotypeResults![genotypeKey] ?? + // Should not be null but to be safe + GenotypeResult.missingResult( + GenotypeKey.extractGene(genotypeKey), + variant: GenotypeKey.maybeExtractVariant(genotypeKey), + ) + ).toList(); +} + Future maybeUpdateDrugsWithGuidelines() async { final isOnline = await hasConnectionTo(anniUrl().host); if (!isOnline && DrugsWithGuidelines.instance.version == null) { diff --git a/app/lib/common/utilities/pdf_utils.dart b/app/lib/common/utilities/pdf_utils.dart index 39daf7cc..9f5c5e8c 100644 --- a/app/lib/common/utilities/pdf_utils.dart +++ b/app/lib/common/utilities/pdf_utils.dart @@ -141,20 +141,10 @@ String? _getPhenotypeInfo(String genotypeKey, Drug drug, BuildContext context) { } String? _getPhenoconversionInfo(Drug drug, BuildContext context) { - if (drug.guidelines.isEmpty) return null; - final inhibitedGenotypes = drug.guidelineGenotypes.map((genotypeKey) => - UserData.instance.genotypeResults![genotypeKey]! - ).filter( - (genotypeResult) => isInhibited(genotypeResult, drug: drug.name) - ).toList(); - if (inhibitedGenotypes.isEmpty) return null; - final tooltipText = getExpertPhenoconversionExplanation( - context, - inhibitedGenotypes, - drug.name, - ); - if (tooltipText.isBlank) return null; - return '$drugInteractionIndicator $tooltipText'; + final phenoconversionExplanation = + getExpertPhenoconversionExplanation(drug, context); + if (phenoconversionExplanation == null) return null; + return '$drugInteractionIndicator $phenoconversionExplanation'; } String? _getActivityScoreInfo( diff --git a/app/lib/common/widgets/phenoconversion_explanation.dart b/app/lib/common/widgets/phenoconversion_explanation.dart index 67ae5956..c9796a65 100644 --- a/app/lib/common/widgets/phenoconversion_explanation.dart +++ b/app/lib/common/widgets/phenoconversion_explanation.dart @@ -1,7 +1,7 @@ import '../module.dart'; -class _PhenoconversionDisplayConfig { - _PhenoconversionDisplayConfig({ +class PhenoconversionDisplayConfig { + PhenoconversionDisplayConfig({ required this.partSeparator, required this.userSalutation, required this.userGenitive, @@ -14,17 +14,81 @@ class _PhenoconversionDisplayConfig { final bool useConsult; } -String getExpertPhenoconversionExplanation( - BuildContext context, +enum PhenoconversionDisplayType { + user, + expert +} + +extension on PhenoconversionDisplayType { + PhenoconversionDisplayConfig getConfig(BuildContext context) { + switch (this) { + case PhenoconversionDisplayType.expert: + return PhenoconversionDisplayConfig( + partSeparator: ' ', + userSalutation: context.l10n.inhibitor_third_person_salutation, + userGenitive: context.l10n.inhibitor_third_person_salutation_genitive, + useConsult: false, + ); + default: + return PhenoconversionDisplayConfig( + partSeparator: '\n\n', + userSalutation: context.l10n.inhibitor_direct_salutation, + userGenitive: context.l10n.inhibitor_direct_salutation_genitive, + useConsult: true, + ); + } + } +} + +typedef PhenoconversionExplanationBuilder = dynamic Function( List inhibitedGenotypes, String drugName, -) { - final displayConfig = _PhenoconversionDisplayConfig( - partSeparator: ' ', - userSalutation: context.l10n.inhibitor_third_person_salutation, - userGenitive: context.l10n.inhibitor_third_person_salutation_genitive, - useConsult: false, + BuildContext? context, +); + +dynamic _getPhenoconversionExplanation({ + required Drug drug, + required PhenoconversionExplanationBuilder explanationBuilder, + BuildContext? context, +}) { + final inhibitedGenotypes = getInhibitedGenotypesForDrug(drug); + if (inhibitedGenotypes.isEmpty) return null; + return explanationBuilder(inhibitedGenotypes, drug.name, context); +} + +Widget? getUserPhenoconversionExplanation(Drug drug) { + return _getPhenoconversionExplanation( + drug: drug, + explanationBuilder: (inhibitedGenotypes, drugName, _) => + PhenoconversionExplanation( + inhibitedGenotypes: inhibitedGenotypes, + drugName: drugName, + displayType: PhenoconversionDisplayType.user, + ), ); +} + +String? getExpertPhenoconversionExplanation(Drug drug, BuildContext context) { + return _getPhenoconversionExplanation( + drug: drug, + explanationBuilder: (inhibitedGenotypes, drugName, context) => + getPhenoconversionExplanationString( + context: context!, + inhibitedGenotypes: inhibitedGenotypes, + drugName: drugName, + displayType: PhenoconversionDisplayType.expert, + ), + context: context, + ); +} + +String? getPhenoconversionExplanationString({ + required BuildContext context, + required List inhibitedGenotypes, + required String drugName, + required PhenoconversionDisplayType displayType, +}) { + final displayConfig = displayType.getConfig(context); return inhibitedGenotypes.flatMap((genotypeResult) => [ _getPhenoconversionDetailText(context, genotypeResult, drug: drugName, displayConfig: displayConfig), // TODO: get list @@ -36,19 +100,16 @@ class PhenoconversionExplanation extends StatelessWidget { super.key, required this.inhibitedGenotypes, required this.drugName, + this.displayType = PhenoconversionDisplayType.user, }); final List inhibitedGenotypes; final String? drugName; + final PhenoconversionDisplayType displayType; @override Widget build(BuildContext context) { - final displayConfig = _PhenoconversionDisplayConfig( - partSeparator: '\n\n', - userSalutation: context.l10n.inhibitor_direct_salutation, - userGenitive: context.l10n.inhibitor_direct_salutation_genitive, - useConsult: true, - ); + final displayConfig = displayType.getConfig(context); return PrettyExpansionTile( title: buildTable([ TableRowDefinition( @@ -86,7 +147,7 @@ String _getPhenoconversionDetailText( GenotypeResult genotypeResult, { required String? drug, - required _PhenoconversionDisplayConfig displayConfig, + required PhenoconversionDisplayConfig displayConfig, }) { final activeInhibitors = activeInhibitorsFor( diff --git a/app/lib/drug/widgets/annotation_cards/guideline.dart b/app/lib/drug/widgets/annotation_cards/guideline.dart index ee1f9195..49d63bff 100644 --- a/app/lib/drug/widgets/annotation_cards/guideline.dart +++ b/app/lib/drug/widgets/annotation_cards/guideline.dart @@ -125,22 +125,8 @@ class GuidelineAnnotationCard extends StatelessWidget { : context.l10n.drugs_page_tooltip_guideline_missing; } - List? _getGenotypeResults() { - if (drug.userGuideline == null && drug.guidelines.isEmpty) { - return null; - } - return drug.guidelineGenotypes.map((genotypeKey) => - UserData.instance.genotypeResults![genotypeKey] ?? - // Should not be null but to be safe - GenotypeResult.missingResult( - GenotypeKey.extractGene(genotypeKey), - variant: GenotypeKey.maybeExtractVariant(genotypeKey), - ) - ).toList(); - } - Widget _buildPhenotype(BuildContext context) { - final genotypeResults = _getGenotypeResults(); + final genotypeResults = getGenotypeResultsForDrug(drug); if (genotypeResults == null) { return Text( context.l10n.drugs_page_guidelines_empty(drug.name), @@ -162,20 +148,12 @@ class GuidelineAnnotationCard extends StatelessWidget { } Widget? _maybeBuildPhenoconversionInformation(BuildContext context) { - final genotypeResults = _getGenotypeResults(); - final inhibitedGenotypes = genotypeResults?.filter( - (genotypeResult) => isInhibited(genotypeResult, drug: drug.name) - ).toList() ?? []; - if (inhibitedGenotypes.isNotEmpty) { - return Padding( - padding: EdgeInsets.only(top: PharMeTheme.smallSpace), - child: PhenoconversionExplanation( - inhibitedGenotypes: inhibitedGenotypes, - drugName: drug.name, - ), - ); - } - return null; + final phenoconversionExplanation = getUserPhenoconversionExplanation(drug); + if (phenoconversionExplanation == null) return null; + return Padding( + padding: EdgeInsets.only(top: PharMeTheme.smallSpace), + child: phenoconversionExplanation, + ); } Widget _buildSourcesSection(BuildContext context) {