Skip to content

Commit

Permalink
feat(#636): improve cards and list dividers
Browse files Browse the repository at this point in the history
  • Loading branch information
tamslo committed Dec 21, 2023
1 parent 80615ea commit 0da27c3
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 88 deletions.
2 changes: 2 additions & 0 deletions app/lib/common/theme.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'module.dart';
import 'utilities/color_utils.dart';

class PharMeTheme {
static ThemeData get light {
Expand Down Expand Up @@ -81,6 +82,7 @@ class PharMeTheme {
static const backgroundColor = Colors.white;
static const errorColor = Color(0xccf52a2a);
static final borderColor = Colors.black.withOpacity(.2);
static final iconColor = darkenColor(PharMeTheme.onSurfaceText, -0.1);

static const smallSpace = 8.0;
static const smallToMediumSpace = 12.0;
Expand Down
2 changes: 1 addition & 1 deletion app/lib/common/utilities/color_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import '../module.dart';

// From https://stackoverflow.com/a/58604669
Color darkenColor(Color color, [double amount = 0.1]) {
assert(amount >= 0 && amount <= 1);
assert(amount >= -1 && amount <= 1);
final hsl = HSLColor.fromColor(color);
final hslDark = hsl.withLightness((hsl.lightness - amount).clamp(0.0, 1.0));
return hslDark.toColor();
Expand Down
4 changes: 2 additions & 2 deletions app/lib/common/widgets/drug_list/drug_items/drug_cards.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ class DrugCard extends StatelessWidget {
final drugName = formatDrugName(drug, showDrugInteractionIndicator);
return RoundedCard(
onTap: onTap,
innerPadding: EdgeInsets.all(PharMeTheme.smallSpace),
radius: 16,
innerPadding: EdgeInsets.all(PharMeTheme.smallSpace * 1.15),
radius: 18,
color: drug.warningLevel.color,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ List<Widget> buildDrugCheckboxList(
);
return [
SubheaderDivider(
context.l10n.drug_selection_subheader_active_drugs,
text: context.l10n.drug_selection_subheader_active_drugs,
key: Key('header-active'),
),
...activeDrugsList,
SubheaderDivider(
context.l10n.drug_selection_subheader_all_drugs,
text: context.l10n.drug_selection_subheader_all_drugs,
key: Key('header-all'),
),
...allDrugsList,
Expand Down
28 changes: 13 additions & 15 deletions app/lib/common/widgets/rounded_card.dart
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
import '../module.dart';
import '../utilities/color_utils.dart';

class RoundedCard extends StatelessWidget {
const RoundedCard({
this.innerPadding,
this.outerPadding,
this.color = PharMeTheme.surfaceColor,
this.outerVerticalPadding,
this.outerHorizontalPadding,
this.color,
this.radius = 20,
this.onTap,
required this.child,
super.key,
});

final EdgeInsets? innerPadding;
final EdgeInsets? outerPadding;
final double? outerVerticalPadding;
final double? outerHorizontalPadding;
final VoidCallback? onTap;
final Color color;
final Color? color;
final double radius;
final Widget child;

@override
Widget build(BuildContext context) {
Widget child = Padding(
padding: innerPadding ?? EdgeInsets.all(PharMeTheme.mediumSpace),
padding: innerPadding ?? EdgeInsets.all(PharMeTheme.smallSpace * 1.25),
child: this.child,
);

Expand All @@ -30,20 +34,14 @@ class RoundedCard extends StatelessWidget {
return Container(
width: double.infinity,
child: Padding(
padding: outerPadding ?? EdgeInsets.symmetric(
horizontal: PharMeTheme.smallSpace,
vertical: PharMeTheme.smallSpace / 2
padding: EdgeInsets.symmetric(
vertical: outerVerticalPadding ?? PharMeTheme.smallSpace * 0.65,
horizontal: outerHorizontalPadding ?? PharMeTheme.smallSpace,
),
child: DecoratedBox(
decoration: BoxDecoration(
color: color,
color: color ?? darkenColor(PharMeTheme.onSurfaceColor, -0.05),
borderRadius: BorderRadius.all(Radius.circular(radius)),
boxShadow: [
BoxShadow(
color: PharMeTheme.onSurfaceColor,
blurRadius: 16,
),
],
),
child: child,
),
Expand Down
8 changes: 5 additions & 3 deletions app/lib/common/widgets/subheader_divider.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import '../module.dart';

class SubheaderDivider extends StatelessWidget {
const SubheaderDivider(
this.text, {
const SubheaderDivider({
this.text = '',
this.indent = 20.0,
this.color,
this.useLine = true,
super.key,
});

final String text;
final double indent;
final Color? color;
final bool useLine;

@override
Widget build(BuildContext context) {
Expand All @@ -20,7 +22,7 @@ class SubheaderDivider extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Divider(color: widgetColor),
if (useLine) Divider(color: widgetColor, thickness: 0.5),
Text(
text,
style:
Expand Down
81 changes: 52 additions & 29 deletions app/lib/faq/pages/faq.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,65 +11,87 @@ class FaqPage extends StatelessWidget {
canPop: false,
child: pageScaffold(title: context.l10n.tab_faq, body: [
Padding(
padding: const EdgeInsets.all(8),
padding: const EdgeInsets.all(PharMeTheme.smallSpace),
child: Column(
key: Key('questionsColumn'),
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 8),
...faqList.keys.fold<List<Widget>>(
[], (widgets, topic) =>
[...widgets, ..._buildTopic(context, topic, faqList[topic]!)]
),
Divider(),
ListTile(
..._buildTopicHeader(
context.l10n.settings_page_contact_us,
addSpace: true,
),
_buildQuestionCard(
child: ListTile(
title: Text(context.l10n.faq_contact_us),
trailing: Icon(Icons.chevron_right_rounded),
onTap: sendEmail)
iconColor: PharMeTheme.iconColor,
onTap: sendEmail
)
)

],
),
),
]),
);
}

List<Widget> _buildTopicHeader(String title, { required bool addSpace }) => [
if (addSpace) SizedBox(height: PharMeTheme.mediumSpace),
SubheaderDivider(text: title, useLine: false),
];

Widget _buildQuestionCard({ required Widget child, Key? key }) => RoundedCard(
key: key,
innerPadding: EdgeInsets.all(PharMeTheme.smallSpace * 0.25),
child: child,
);

List<Widget> _buildTopic(
BuildContext context,
String topicName,
List<Question> questions
) {
final topicIndex = faqList.keys.toList().indexOf(topicName);
return [
ListTile(
title: Text(
topicName,
style: PharMeTheme.textTheme.bodyMedium,
),
dense: true,
),
..._buildTopicHeader(topicName, addSpace: topicIndex != 0),
...questions.map((question) => _buildQuestion(context, question))
];
}

Widget _buildQuestion(BuildContext context, Question question) {
final key = GlobalKey();

return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: ExpansionTile(
key: key,
title: Text(question.question),
onExpansionChanged: (value) {
if (value) _scrollToSelectedContent(key: key);
},
children: [
ListTile(
contentPadding: EdgeInsets.only(left: 16, right: 16, bottom: 8),
title: Text(question.answer),
return _buildQuestionCard(
key: key,
child: Theme(
data: Theme.of(context).copyWith(
dividerColor: Colors.transparent,
),
child: ExpansionTile(
title: Text(question.question),
iconColor: PharMeTheme.iconColor,
collapsedIconColor: PharMeTheme.iconColor,
onExpansionChanged: (value) {
if (value) _scrollToSelectedContent(key: key);
},
children: [
ListTile(
contentPadding: EdgeInsets.only(
left: PharMeTheme.mediumSpace,
right: PharMeTheme.mediumSpace,
bottom: PharMeTheme.smallSpace,
),
title: Text(question.answer),
),
],
),
),
],
),
);
);
}

void _scrollToSelectedContent({required GlobalKey key}) {
Expand All @@ -79,6 +101,7 @@ class FaqPage extends StatelessWidget {
Scrollable.ensureVisible(
keyContext,
duration: Duration(milliseconds: 200),
alignmentPolicy: ScrollPositionAlignmentPolicy.keepVisibleAtEnd,
);
});
}
Expand Down
2 changes: 2 additions & 0 deletions app/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"update_warning_title": "Updated guidelines",
"update_warning_body": "The guidelines for gene-drug interactions were updated. Please review your information, especially for medications you are currently taking.",


"faq_contact_us": "Do you have unanswered questions or feedback? Contact us",

"general_continue": "Continue",
Expand Down Expand Up @@ -354,6 +355,7 @@
"settings_page_privacy_policy_text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"settings_page_terms_and_conditions": "Terms of use",
"settings_page_terms_and_conditions_text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"settings_page_help_and_feedback": "Help & Feedback",
"settings_page_contact_us": "Contact us",

"comprehension_intro_text": "Would you like to participate in a survey aiming to measure user comprehension of content in the app? This would help us make PharMe more understandable for everyone!",
Expand Down
69 changes: 34 additions & 35 deletions app/lib/more/pages/more.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,64 +10,63 @@ class MorePage extends StatelessWidget {
return PopScope(
canPop: false,
child: pageScaffold(title: context.l10n.tab_more, body: [
ListTile(
title: Text(
context.l10n.settings_page_account_settings,
style: PharMeTheme.textTheme.bodyMedium,
),
dense: true,
SubheaderDivider(
text: context.l10n.settings_page_account_settings,
useLine: false,
),
ListTile(
title: Text(context.l10n.drug_selection_header),
trailing: Icon(Icons.chevron_right_rounded),
_buildSettingsItem(
title: context.l10n.drug_selection_header,
onTap: () => context.router.push(
DrugSelectionRoute(concludesOnboarding: false)
),
),
ListTile(
title: Text(context.l10n.settings_page_delete_data),
trailing: Icon(Icons.chevron_right_rounded),
_buildSettingsItem(
title: context.l10n.settings_page_delete_data,
onTap: () => showDialog(
context: context,
builder: (_) => DeleteDataDialog(),
),
),
Divider(),
ListTile(
title: Text(
context.l10n.settings_page_more,
style: PharMeTheme.textTheme.bodyMedium,
),
dense: true,
SubheaderDivider(
text: context.l10n.settings_page_more,
useLine: false,
),
ListTile(
title: Text(context.l10n.settings_page_onboarding),
trailing: Icon(Icons.chevron_right_rounded),
_buildSettingsItem(
title: context.l10n.settings_page_onboarding,
onTap: () => context.router.push(OnboardingRoute(isRevisiting: true)),
),
ListTile(
title: Text(context.l10n.settings_page_about_us),
trailing: Icon(Icons.chevron_right_rounded),
_buildSettingsItem(
title: context.l10n.settings_page_about_us,
onTap: () => context.router.push(AboutRoute()),
),
ListTile(
title: Text(context.l10n.settings_page_privacy_policy),
trailing: Icon(Icons.chevron_right_rounded),
_buildSettingsItem(
title: context.l10n.settings_page_privacy_policy,
onTap: () => context.router.push(PrivacyRoute()),
),
ListTile(
title: Text(context.l10n.settings_page_terms_and_conditions),
trailing: Icon(Icons.chevron_right_rounded),
_buildSettingsItem(
title: context.l10n.settings_page_terms_and_conditions,
onTap: () => context.router.push(TermsRoute()),
),
Divider(),
ListTile(
title: Text(context.l10n.settings_page_contact_us),
trailing: Icon(Icons.chevron_right_rounded),
SubheaderDivider(
text: context.l10n.settings_page_help_and_feedback,
useLine: false,
),
_buildSettingsItem(
title: context.l10n.settings_page_contact_us,
onTap: sendEmail)
]),
);
}

Widget _buildSettingsItem({
required String title,
required void Function() onTap,
}) => ListTile(
title: Text(title),
trailing: Icon(Icons.chevron_right_rounded),
iconColor: PharMeTheme.iconColor,
onTap: onTap,
);
}

class DeleteDataDialog extends HookWidget {
Expand Down
1 change: 0 additions & 1 deletion app/lib/report/pages/report.dart
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ class GeneCard extends StatelessWidget {
).toList();
return RoundedCard(
onTap: () => context.router.push(GeneRoute(phenotype: phenotype)),
innerPadding: EdgeInsets.all(PharMeTheme.smallSpace),
radius: 16,
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Expanded(
Expand Down

0 comments on commit 0da27c3

Please sign in to comment.