diff --git a/app/lib/common/theme.dart b/app/lib/common/theme.dart index 5c391e35..65de5f25 100644 --- a/app/lib/common/theme.dart +++ b/app/lib/common/theme.dart @@ -84,6 +84,7 @@ class PharMeTheme { static const errorColor = Color(0xccf52a2a); static final borderColor = Colors.black.withOpacity(.2); static final iconColor = darkenColor(PharMeTheme.onSurfaceText, -0.1); + static final buttonColor = darkenColor(PharMeTheme.iconColor, -0.1); static final subheaderColor = Colors.grey[600]; static const smallSpace = 8.0; diff --git a/app/lib/common/widgets/drug_search/drug_filters.dart b/app/lib/common/widgets/drug_search/drug_filters.dart index 0118e93d..38304241 100644 --- a/app/lib/common/widgets/drug_search/drug_filters.dart +++ b/app/lib/common/widgets/drug_search/drug_filters.dart @@ -212,7 +212,7 @@ class DrugFilters extends StatelessWidget { return ResizedIconButton( onPressed: onPressed, size: PharMeTheme.largeSpace, - backgroundColor: darkenColor(PharMeTheme.iconColor, -0.1), + backgroundColor: PharMeTheme.buttonColor, iconWidgetBuilder: (size) => Stack( children: [ Icon( diff --git a/app/lib/common/widgets/resized_icon_button.dart b/app/lib/common/widgets/resized_icon_button.dart index d093fa79..0be65c19 100644 --- a/app/lib/common/widgets/resized_icon_button.dart +++ b/app/lib/common/widgets/resized_icon_button.dart @@ -13,12 +13,14 @@ class ResizedIconButton extends StatelessWidget { required this.size, this.onPressed, this.backgroundColor, + this.disabledBackgroundColor, }); final Widget Function(double? size) iconWidgetBuilder; final double size; final void Function()? onPressed; final Color? backgroundColor; + final Color? disabledBackgroundColor; @override Widget build(BuildContext context) { @@ -30,7 +32,10 @@ class ResizedIconButton extends StatelessWidget { padding: EdgeInsets.all(padding), onPressed: onPressed, icon: iconWidgetBuilder(size - 2 * padding), - style: IconButton.styleFrom(backgroundColor: backgroundColor), + style: IconButton.styleFrom( + backgroundColor: backgroundColor, + disabledBackgroundColor: disabledBackgroundColor, + ), ), ); } diff --git a/app/lib/l10n/app_en.arb b/app/lib/l10n/app_en.arb index 3e99a147..b90fbd55 100644 --- a/app/lib/l10n/app_en.arb +++ b/app/lib/l10n/app_en.arb @@ -262,8 +262,8 @@ "report_content_explanation": "This is your PGx test report. Tap on a gene name for more details on your results and a list of implicated medications.", "@report_content_explanation": {}, - "report_legend_text": "Next to your gene result the number of implicated medications per guideline result is shown:", - "@report_legend_text": {}, + "report_page_dropdown_text": "Having trouble finding a gene? Use the ▾ button above to change between showing only genes associated with your current medications or showing all genes with known medication interactions.", + "@report_page_dropdown_text": {}, "report_page_faq_tooltip": "To learn more about genetics in general, please refer to the FAQ", "@report_page_faq_tooltip": {}, "report_page_indicator_explanation": "Phenotypes followed by an {indicatorName} ({indicator}) might be adjusted based on interactions with medications you are currently taking", @@ -279,17 +279,12 @@ } } }, - "report_current_medications": "Gene report for current medication interactions ({geneNumber} genes)", - "@report_current_medications": { - "placeholders": { - "geneNumber": { - "type": "int", - "example": "3" - } - } - }, - "report_all_medications": "Gene report for all known medication interactions ({geneNumber} genes)", - "@report_all_medications": { + "report_current_medications": "Gene report for current medication interactions", + "@report_current_medications": {}, + "report_all_medications": "Gene report for all known medication interactions", + "@report_all_medications": {}, + "report_gene_number": " ({geneNumber} genes)", + "@report_gene_number": { "placeholders": { "geneNumber": { "type": "int", diff --git a/app/lib/report/pages/report.dart b/app/lib/report/pages/report.dart index bbf921d2..dfbdbfd6 100644 --- a/app/lib/report/pages/report.dart +++ b/app/lib/report/pages/report.dart @@ -4,14 +4,34 @@ import 'package:provider/provider.dart'; import '../../common/module.dart'; typedef WarningLevelCounts = Map; +class ListOption { + ListOption({required this.label, this.drugSubset}); + Widget getDescription(BuildContext context, int geneNumber) { + return Text.rich( + style: PharMeTheme.textTheme.labelLarge, + TextSpan( + children: [ + TextSpan(text: label, style: TextStyle(fontWeight: FontWeight.bold)), + TextSpan( + text: context.l10n.report_gene_number(geneNumber), + style: TextStyle(color: PharMeTheme.buttonColor), + ), + ], + ), + ); + } + final String label; + final List? drugSubset; +} @RoutePage() -class ReportPage extends StatelessWidget { +class ReportPage extends HookWidget { @override Widget build(BuildContext context) { + final currentListOption = useState(0); return Consumer( builder: (context, activeDrugs, child) => - _buildReportPage(context, activeDrugs) + _buildReportPage(context, activeDrugs, currentListOption) ); } @@ -86,9 +106,23 @@ class ReportPage extends StatelessWidget { ).toList(); } - Widget _buildReportPage(BuildContext context, ActiveDrugs activeDrugs) { - final currentMedicationGeneCards = _buildGeneCards(drugsToFilterBy: activeDrugs.names); - final allGeneCards = _buildGeneCards(); + Widget _buildReportPage( + BuildContext context, + ActiveDrugs activeDrugs, + ValueNotifier currentListOptionIndex, + ) { + final listOptions = [ + ListOption( + label: context.l10n.report_current_medications, + drugSubset: activeDrugs.names, + ), + ListOption(label: context.l10n.report_all_medications), + ]; + final currentListOption = listOptions[currentListOptionIndex.value]; + final geneCards = _buildGeneCards( + drugsToFilterBy: currentListOption.drugSubset, + ); + // TODO: only for currently shown genes final hasActiveInhibitors = activeDrugs.names.any(isInhibitor); return PopScope( canPop: false, @@ -100,48 +134,54 @@ class ReportPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ PageDescription.fromText(context.l10n.report_content_explanation), - scrollList( - [ - PageDescription( - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(context.l10n.report_legend_text), - SizedBox(height: PharMeTheme.smallSpace * 0.5), - Text.rich(buildWarningLevelTextLegend(context)), - ] - ), - ), - if (currentMedicationGeneCards.isNotEmpty) ...[ - SubheaderDivider( - text: context.l10n.report_current_medications( - currentMedicationGeneCards.length, + Padding( + key: Key('gene-report-selection'), + padding: EdgeInsets.only( + top: PharMeTheme.smallSpace, + left: PharMeTheme.smallSpace, + bottom: PharMeTheme.smallSpace, + right: PharMeTheme.mediumToLargeSpace, + ), + child: DropdownButtonHideUnderline( + child: DropdownButton( + isExpanded: true, + isDense: false, + value: currentListOptionIndex.value, + onChanged: (index) => currentListOptionIndex.value = + index ?? currentListOptionIndex.value, + icon: ResizedIconButton( + size: PharMeTheme.largeSpace, + disabledBackgroundColor: PharMeTheme.buttonColor, + iconWidgetBuilder: (size) => Icon( + Icons.arrow_drop_down, + size: size, + color: PharMeTheme.surfaceColor, ), - key: Key('header-current'), - useLine: false, ), - ...currentMedicationGeneCards, - ], - if ( - allGeneCards.isNotEmpty && - currentMedicationGeneCards.isNotEmpty - ) PrettyExpansionTile( - key: Key('header-all'), - title: SubheaderDivider( - text: context.l10n.report_all_medications( - allGeneCards.length, + items: listOptions.mapIndexed( + (index, listOption) => DropdownMenuItem( + value: index, + child: listOption.getDescription( + context, + _buildGeneCards( + drugsToFilterBy: listOption.drugSubset, + ).length ), - useLine: false, ), - initiallyExpanded: true, - visualDensity: VisualDensity.compact, - titlePadding: EdgeInsets.zero, - childrenPadding: EdgeInsets.zero, - children: allGeneCards, - ), - if (currentMedicationGeneCards.isEmpty) ...allGeneCards, - ], + ).toList(), + ), + ), ), + scrollList([ + ...geneCards, + if (currentListOption.drugSubset != null) ...[ + SizedBox( + key: Key('gene-spacer'), + height: PharMeTheme.mediumSpace, + ), + PageDescription.fromText(context.l10n.report_page_dropdown_text), + ] + ]), if (hasActiveInhibitors) PageIndicatorExplanation( context.l10n.report_page_indicator_explanation( drugInteractionIndicatorName, @@ -203,7 +243,7 @@ class GeneCard extends StatelessWidget { WidgetSpan(child: Icon( FontAwesomeIcons.pills, size: PharMeTheme.textTheme.bodyMedium!.fontSize, - color: darkenColor(PharMeTheme.iconColor, -0.1), + color: PharMeTheme.buttonColor, )), TextSpan(text: ' : '), buildWarningLevelLegend(