Skip to content

Commit

Permalink
feat(app): show contacting dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
tamslo committed Sep 2, 2024
1 parent f4efef1 commit dbd2569
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 30 deletions.
26 changes: 0 additions & 26 deletions app/lib/common/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,6 @@ Uri labServerUrl([String slug = '']) =>
Uri keycloakUrl([String slug = '']) =>
Uri.http('vm-slosarek01.dhclab.i.hpi.de:28080', slug);

// Note that sending emails will not work on the iPhone Simulator since it does
// not have any email application installed.
String contactEmailAddress = '[email protected]';
// Workaround according to https://pub.dev/packages/url_launcher#encoding-urls
String? _encodeQueryParameters(Map<String, String> params) {
return params.entries
.map((entry) =>
'${Uri.encodeComponent(entry.key)}=${Uri.encodeComponent(entry.value)}'
).join('&');
}
Future<void> sendEmail({
String subject = '',
String body = '',
}) async {
await launchUrl(
Uri(
scheme: 'mailto',
path: contactEmailAddress,
query: _encodeQueryParameters({
'subject': subject,
'body': body,
}),
),
);
}

final geneticInformationUrl = Uri.https(
'medlineplus.gov',
'/genetics/understanding/',
Expand Down
146 changes: 146 additions & 0 deletions app/lib/common/utilities/contact.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import 'package:flutter/services.dart';
import 'package:url_launcher/url_launcher.dart';

import '../module.dart';

// Note that sending emails will not work on the iPhone Simulator since it does
// not have any email application installed.

String contactEmailAddress = '[email protected]';

class CopyText extends HookWidget {
const CopyText({
required this.text,
this.label,
this.bold = false,
this.scrollable = false,
});

final String text;
final String? label;
final bool bold;
final bool scrollable;

@override
Widget build(BuildContext context) {
final copySuccess = useState<bool>(false);
var textStyle = TextStyle();
if (bold) textStyle = textStyle.copyWith(fontWeight: FontWeight.bold);
if (scrollable) {
textStyle = textStyle.copyWith(
backgroundColor: PharMeTheme.onSurfaceColor,
);
}
final textComponent = Text(
text,
style: textStyle,
maxLines: 1,
);
final icon = copySuccess.value
? Icons.check
: Icons.copy;
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (label.isNotNullOrBlank) ...[
Text(
label!,
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(width: PharMeTheme.smallSpace),
],
Expanded(
child: scrollable
? SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: textComponent,
)
: textComponent,
),
SizedBox(width: PharMeTheme.smallSpace),
GestureDetector(
child: Icon(
icon,
color: PharMeTheme.iconColor,
size: PharMeTheme.mediumSpace,
),
onTap: () async => {
copySuccess.value = true,
await Clipboard.setData(ClipboardData(text: text)),
Future.delayed(Duration(seconds: 1), () => copySuccess.value = false),
},
),
],
);
}

}

// Workaround according to https://pub.dev/packages/url_launcher#encoding-urls
String? _encodeQueryParameters(Map<String, String> params) {
return params.entries
.map((entry) =>
'${Uri.encodeComponent(entry.key)}=${Uri.encodeComponent(entry.value)}'
).join('&');
}
Future<void> sendEmail(BuildContext context, {
String subject = '',
String body = '',
}) async {
await showAdaptiveDialog(
context: context,
builder: (context) => DialogWrapper(
title: context.l10n.more_page_contact_us,
content: SingleChildScrollView(
child: Column(
children: [
SizedBox(height: PharMeTheme.smallSpace),
Text(context.l10n.contact_text),
SizedBox(height: PharMeTheme.smallSpace),
CopyText(text: contactEmailAddress, bold: true),
if (subject.isNotBlank || body.isNotBlank) ...[
SizedBox(height: PharMeTheme.smallSpace),
Text(context.l10n.contact_context_text),
if (subject.isNotBlank) ...[
SizedBox(height: PharMeTheme.smallSpace),
CopyText(
text: subject,
label: context.l10n.contact_subject,
scrollable: true,
),
],
if (body.isNotBlank) ...[
SizedBox(height: PharMeTheme.smallSpace),
CopyText(
text: body,
label: context.l10n.contact_body,
scrollable: true,
),
],
],
],
),
),
actions: [
DialogAction(
text: context.l10n.action_cancel,
onPressed: () => Navigator.pop(context),
),
DialogAction(
text: context.l10n.contact_open_mail,
isDefault: true,
onPressed: () async => launchUrl(
Uri(
scheme: 'mailto',
path: contactEmailAddress,
query: _encodeQueryParameters({
'subject': subject,
'body': body,
}),
),
),
),
],
),
);
}
1 change: 1 addition & 0 deletions app/lib/common/utilities/module.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export 'color_utils.dart';
export 'contact.dart';
export 'drug_utils.dart';
export 'genome_data.dart';
export 'material_colors.dart';
Expand Down
3 changes: 3 additions & 0 deletions app/lib/common/widgets/dialog_action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ class DialogAction extends StatelessWidget {
const DialogAction({
super.key,
this.isDestructive = false,
this.isDefault = false,
this.onPressed,
required this.text,
});

final bool isDestructive;
final bool isDefault;
final void Function()? onPressed;
final String text;

Expand All @@ -20,6 +22,7 @@ class DialogAction extends StatelessWidget {
case SupportedPlatform.ios:
return CupertinoDialogAction(
isDestructiveAction: isDestructive,
isDefaultAction: isDefault,
onPressed: onPressed,
child: Text(text),
);
Expand Down
1 change: 1 addition & 0 deletions app/lib/error/pages/error.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class ErrorPage extends StatelessWidget {
text: contactEmailAddress,
style: PharMeTheme.textTheme.bodyLarge,
onTap: () => sendEmail(
context,
subject: context.l10n.error_mail_subject,
body: context.l10n.error_mail_body(error),
),
Expand Down
5 changes: 2 additions & 3 deletions app/lib/faq/pages/faq.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@ class FaqPage extends StatelessWidget {
title: Text(context.l10n.faq_contact_us),
trailing: Icon(Icons.chevron_right_rounded),
iconColor: PharMeTheme.iconColor,
onTap: sendEmail
onTap: () => sendEmail(context),
)
)

),
],
),
),
Expand Down
6 changes: 6 additions & 0 deletions app/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,12 @@
"more_page_genetic_information": "Learn about genetics (MedlinePlus)",
"more_page_contact_us": "Contact us",

"contact_text": "You can contact us using the following email address:",
"contact_context_text": "To help us to understand the context of your message, please include the following information:",
"contact_subject": "Subject:",
"contact_body": "Text:",
"contact_open_mail": "Send mail",

"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!",
"comprehension_survey_button_text": "Continue to survey"
}
2 changes: 1 addition & 1 deletion app/lib/more/pages/more.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class MorePage extends StatelessWidget {
onTap: openFurtherGeneticInformation),
_buildSettingsItem(
title: context.l10n.more_page_contact_us,
onTap: sendEmail)
onTap: () => sendEmail(context)),
]
),
);
Expand Down

0 comments on commit dbd2569

Please sign in to comment.