Skip to content

Commit

Permalink
feat(app): improve inhibitor information (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
tamslo committed Dec 5, 2024
1 parent 5ce2efc commit c89f418
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 203 deletions.
176 changes: 5 additions & 171 deletions app/lib/common/models/drug/drug_inhibitors.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,132 +55,13 @@ bool _isInhibitorOfType(
return influencingDrugs.contains(drugName);
}

bool _isModerateInhibitor(String drugName) {
return _isInhibitorOfType(drugName, moderateDrugInhibitors);
}

class _DisplayConfig {
_DisplayConfig({
required this.partSeparator,
required this.userSalutation,
required this.userGenitive,
required this.useConsult,
});

final String partSeparator;
final String userSalutation;
final String userGenitive;
final bool useConsult;
}

_DisplayConfig _getDisplayConfig(
BuildContext context,
{ required bool userFacing }
) {
final displayConfigs = <bool, _DisplayConfig>{
true: _DisplayConfig(
partSeparator: '\n\n',
userSalutation: context.l10n.inhibitor_direct_salutation,
userGenitive: context.l10n.inhibitor_direct_salutation_genitive,
useConsult: true,
),
false: _DisplayConfig(
partSeparator: ' ',
userSalutation: context.l10n.inhibitor_third_person_salutation,
userGenitive: context.l10n.inhibitor_third_person_salutation_genitive,
useConsult: false,
),
};
return displayConfigs[userFacing]!;
}

String _getPhenoconversionConsequence(
BuildContext context,
GenotypeResult genotypeResult,
{
required String? drug,
required _DisplayConfig displayConfig,
}
) {
final activeInhibitors = _activeInhibitorsFor(
genotypeResult.gene,
drug: drug,
);
return activeInhibitors.all(_isModerateInhibitor)
? context.l10n.inhibitors_consequence_not_adapted(
genotypeResult.geneDisplayString,
displayConfig.userGenitive,
).capitalize()
: context.l10n.inhibitors_consequence_adapted(
genotypeResult.geneDisplayString,
genotypeResult.phenotypeDisplayString(context),
displayConfig.userGenitive,
).capitalize();
}

String _getInhibitorsString(
BuildContext context,
GenotypeResult genotypeResult,
{ required String? drug }
) {
return context.l10n.inhibitors_tooltip(enumerationWithAnd(
getDrugsWithBrandNames(_activeInhibitorsFor(
genotypeResult.gene,
drug: drug,
)),
context,
));
}

String _inhibitionTooltipText(
BuildContext context,
GenotypeResult genotypeResult,
{
required String? drug,
required _DisplayConfig displayConfig,
}
) {
final inhibitorsString = _getInhibitorsString(
context,
genotypeResult,
drug: drug,
);
final consequence = _getPhenoconversionConsequence(
context,
genotypeResult,
drug: drug,
displayConfig: displayConfig,
);
return '$consequence${
displayConfig.useConsult ? ' ${context.l10n.consult_text}' : ''
}${displayConfig.partSeparator}$inhibitorsString';
}
// Public helper functions

Widget _drugInteractionTemplate(
BuildContext context,
String tooltipText,
_DisplayConfig displayConfig,
) {
return PrettyExpansionTile(
title: buildTable([
TableRowDefinition(
drugInteractionIndicator,
context.l10n.inhibitor_message(
displayConfig.userSalutation,
displayConfig.userGenitive,
),
)],
boldHeader: false,
),
titlePadding: EdgeInsets.zero,
childrenPadding: EdgeInsets.all(PharMeTheme.smallSpace),
children: [
Text(tooltipText),
],
);
bool isModerateInhibitor(String drugName) {
return _isInhibitorOfType(drugName, moderateDrugInhibitors);
}

List<String> _activeInhibitorsFor(String gene, { required String? drug }) {
List<String> activeInhibitorsFor(String gene, { required String? drug }) {
return UserData.instance.activeDrugNames == null
? <String>[]
: UserData.instance.activeDrugNames!.filter(
Expand All @@ -190,8 +71,6 @@ List<String> _activeInhibitorsFor(String gene, { required String? drug }) {
).toList();
}

// Public helper functions

final inhibitableGenes = List<String>.from(<String>{
...strongDrugInhibitors.keys,
...moderateDrugInhibitors.keys,
Expand Down Expand Up @@ -219,7 +98,7 @@ bool isInhibited(
GenotypeResult genotypeResult,
{ required String? drug }
) {
final activeInhibitors = _activeInhibitorsFor(
final activeInhibitors = activeInhibitorsFor(
genotypeResult.gene,
drug: drug,
);
Expand Down Expand Up @@ -269,48 +148,3 @@ String possiblyAdaptedPhenotype(
}
return '$overwritePhenotype$drugInteractionIndicator';
}

String inhibitionTooltipText(
BuildContext context,
List<GenotypeResult> genotypeResults,
{
required String? drug,
required bool userFacing,
}
) {
final displayConfig = _getDisplayConfig(context, userFacing: userFacing);
final inhibitedGenotypeResults = genotypeResults.filter(
(genotypeResult) => isInhibited(genotypeResult, drug: drug)
).toList();
var tooltipText = '';
for (final (index, genotypeResult) in inhibitedGenotypeResults.indexed) {
final separator = index == 0 ? '' : displayConfig.partSeparator;
// ignore: use_string_buffers
tooltipText = '$tooltipText$separator${
_inhibitionTooltipText(
context,
genotypeResult,
drug: drug,
displayConfig: displayConfig,
)
}';
}
return tooltipText;
}

Widget buildDrugInteractionInfo(
BuildContext context,
List<GenotypeResult> genotypeResults,
{ required String? drug }
) {
return _drugInteractionTemplate(
context,
inhibitionTooltipText(
context,
genotypeResults,
drug: drug,
userFacing: true,
),
_getDisplayConfig(context, userFacing: true),
);
}
12 changes: 7 additions & 5 deletions app/lib/common/utilities/pdf_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,16 @@ String? _getPhenotypeInfo(String genotypeKey, Drug drug, BuildContext context) {

String? _getPhenoconversionInfo(Drug drug, BuildContext context) {
if (drug.guidelines.isEmpty) return null;
final genotypeResults = drug.guidelineGenotypes.map((genotypeKey) =>
final inhibitedGenotypes = drug.guidelineGenotypes.map((genotypeKey) =>
UserData.instance.genotypeResults![genotypeKey]!
).filter(
(genotypeResult) => isInhibited(genotypeResult, drug: drug.name)
).toList();
final tooltipText = inhibitionTooltipText(
if (inhibitedGenotypes.isEmpty) return null;
final tooltipText = getExpertPhenoconversionExplanation(
context,
genotypeResults,
drug: drug.name,
userFacing: false,
inhibitedGenotypes,
drug.name,
);
if (tooltipText.isBlank) return null;
return '$drugInteractionIndicator $tooltipText';
Expand Down
18 changes: 14 additions & 4 deletions app/lib/common/widgets/gene_modulator_list.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
import '../module.dart';

class GeneModulatorList extends StatelessWidget {
const GeneModulatorList({super.key, required this.geneName, this.drugNames});
const GeneModulatorList({
super.key,
required this.geneName,
this.onlyActiveDrugs = false,
this.displayedDrug,
});

final String geneName;
final List<String>? drugNames;
final bool onlyActiveDrugs;
final String? displayedDrug;

List<String> _getModulatorDrugNames(
Map<String, Map<String, dynamic>>modulatorDefinition,
String geneName,
) {
final allModulatorDrugs = modulatorDefinition[geneName]!.keys.toList();
if (drugNames != null) {
return allModulatorDrugs.filter(drugNames!.contains).toList();
if (onlyActiveDrugs) {
final activeModulators = activeInhibitorsFor(
geneName,
drug: displayedDrug,
);
return allModulatorDrugs.filter(activeModulators.contains).toList();
}
return allModulatorDrugs;
}
Expand Down
1 change: 1 addition & 0 deletions app/lib/common/widgets/module.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export 'page_description.dart';
export 'page_indicator_explanation.dart';
export 'page_scaffold.dart';
export 'pharme_logo_page.dart';
export 'phenoconversion_explanation.dart';
export 'pretty_expansion_tile.dart';
export 'radiant_gradient_mask.dart';
export 'resized_icon_button.dart';
Expand Down
109 changes: 109 additions & 0 deletions app/lib/common/widgets/phenoconversion_explanation.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import '../module.dart';

class _PhenoconversionDisplayConfig {
_PhenoconversionDisplayConfig({
required this.partSeparator,
required this.userSalutation,
required this.userGenitive,
required this.useConsult,
});

final String partSeparator;
final String userSalutation;
final String userGenitive;
final bool useConsult;
}

String getExpertPhenoconversionExplanation(
BuildContext context,
List<GenotypeResult> inhibitedGenotypes,
String drugName,
) {
final displayConfig = _PhenoconversionDisplayConfig(
partSeparator: ' ',
userSalutation: context.l10n.inhibitor_third_person_salutation,
userGenitive: context.l10n.inhibitor_third_person_salutation_genitive,
useConsult: false,
);
return inhibitedGenotypes.flatMap((genotypeResult) => [
_getPhenoconversionDetailText(context, genotypeResult, drug: drugName, displayConfig: displayConfig),
// TODO: get list
]).join(displayConfig.partSeparator);
}

class PhenoconversionExplanation extends StatelessWidget {
const PhenoconversionExplanation({
super.key,
required this.inhibitedGenotypes,
required this.drugName,
});

final List<GenotypeResult> inhibitedGenotypes;
final String? drugName;

@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,
);
return PrettyExpansionTile(
title: buildTable([
TableRowDefinition(
drugInteractionIndicator,
context.l10n.inhibitor_message(
displayConfig.userSalutation,
displayConfig.userGenitive,
),
)],
boldHeader: false,
),
titlePadding: EdgeInsets.zero,
childrenPadding: EdgeInsets.all(PharMeTheme.mediumSpace),
children: inhibitedGenotypes.flatMap(
(genotypeResult) => [
Text(_getPhenoconversionDetailText(
context,
genotypeResult,
drug: drugName,
displayConfig: displayConfig,
)),
GeneModulatorList(
geneName: genotypeResult.gene,
onlyActiveDrugs: true,
displayedDrug: drugName,
),
]
).toList(),
);
}
}

String _getPhenoconversionDetailText(
BuildContext context,
GenotypeResult genotypeResult,
{
required String? drug,
required _PhenoconversionDisplayConfig displayConfig,
})
{
final activeInhibitors = activeInhibitorsFor(
genotypeResult.gene,
drug: drug,
);
final consequence = activeInhibitors.all(isModerateInhibitor)
? context.l10n.inhibitors_consequence_not_adapted(
genotypeResult.geneDisplayString,
displayConfig.userGenitive,
).capitalize()
: context.l10n.inhibitors_consequence_adapted(
genotypeResult.geneDisplayString,
genotypeResult.phenotypeDisplayString(context),
displayConfig.userGenitive,
).capitalize();
return '$consequence${
displayConfig.useConsult ? ' ${context.l10n.consult_text}' : ''
}';
}
Loading

0 comments on commit c89f418

Please sign in to comment.