-
-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add user ID to the subject when pressing email support button (#1777)
In case the `userId` is available, it will be appended to the subject. Part of #1069
- Loading branch information
1 parent
8be6c56
commit 1e81b01
Showing
8 changed files
with
265 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,10 +14,9 @@ import 'package:provider/provider.dart'; | |
import 'package:sharezone/navigation/logic/navigation_bloc.dart'; | ||
import 'package:sharezone/navigation/models/navigation_item.dart'; | ||
import 'package:sharezone/support/support_page_controller.dart'; | ||
import 'package:sharezone_utils/launch_link.dart'; | ||
import 'package:sharezone/widgets/avatar_card.dart'; | ||
import 'package:sharezone_utils/launch_link.dart'; | ||
import 'package:sharezone_widgets/sharezone_widgets.dart'; | ||
import 'package:url_launcher/url_launcher.dart'; | ||
|
||
class SupportPage extends StatelessWidget { | ||
static const String tag = 'support-page'; | ||
|
@@ -232,17 +231,16 @@ class _FreeEmailTile extends StatelessWidget { | |
semanticsLabel: 'E-Mail Icon', | ||
), | ||
title: 'E-Mail', | ||
subtitle: '[email protected]', | ||
subtitle: freeSupportEmail, | ||
onPressed: () async { | ||
final url = Uri.parse(Uri.encodeFull( | ||
'mailto:[email protected]?subject=Ich brauche eure Hilfe! 😭')); | ||
try { | ||
await launchUrl(url); | ||
final controller = context.read<SupportPageController>(); | ||
await controller.sendEmailToFreeSupport(); | ||
} on Exception catch (_) { | ||
if (!context.mounted) return; | ||
showSnackSec( | ||
context: context, | ||
text: 'E-Mail: [email protected]', | ||
text: 'E-Mail: $freeSupportEmail', | ||
); | ||
} | ||
}, | ||
|
@@ -256,7 +254,6 @@ class _PlusEmailTile extends StatelessWidget { | |
|
||
@override | ||
Widget build(BuildContext context) { | ||
const emailAddress = '[email protected]'; | ||
return _SupportCard( | ||
icon: PlatformSvg.asset( | ||
'assets/icons/email.svg', | ||
|
@@ -266,15 +263,14 @@ class _PlusEmailTile extends StatelessWidget { | |
title: 'E-Mail', | ||
subtitle: 'Erhalte eine Rückmeldung innerhalb von wenigen Stunden.', | ||
onPressed: () async { | ||
final url = Uri.parse(Uri.encodeFull( | ||
'mailto:$emailAddress?subject=[💎 Sharezone Plus Support] Meine Anfrage')); | ||
try { | ||
await launchUrl(url); | ||
final controller = context.read<SupportPageController>(); | ||
await controller.sendEmailToPlusSupport(); | ||
} on Exception catch (_) { | ||
if (!context.mounted) return; | ||
showSnackSec( | ||
context: context, | ||
text: 'E-Mail: $emailAddress', | ||
text: 'E-Mail: $plusSupportEmail', | ||
); | ||
} | ||
}, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,8 +10,12 @@ import 'dart:async'; | |
|
||
import 'package:common_domain_models/common_domain_models.dart'; | ||
import 'package:flutter/material.dart'; | ||
import 'package:url_launcher_extended/url_launcher_extended.dart'; | ||
import 'package:user/user.dart'; | ||
|
||
const freeSupportEmail = '[email protected]'; | ||
const plusSupportEmail = '[email protected]'; | ||
|
||
class SupportPageController extends ChangeNotifier { | ||
bool get hasPlusSupportUnlocked => | ||
_hasSharezonePlus && _typeOfUser == TypeOfUser.student; | ||
|
@@ -30,6 +34,7 @@ class SupportPageController extends ChangeNotifier { | |
late StreamSubscription<bool> _hasPlusSupportUnlockedSubscription; | ||
late StreamSubscription<bool> _isUserInGroupOnboardingSubscription; | ||
late StreamSubscription<TypeOfUser?> _typeOfUserSubscription; | ||
final UrlLauncherExtended _urlLauncher; | ||
|
||
SupportPageController({ | ||
required Stream<UserId?> userIdStream, | ||
|
@@ -38,7 +43,8 @@ class SupportPageController extends ChangeNotifier { | |
required Stream<bool> hasPlusSupportUnlockedStream, | ||
required Stream<bool> isUserInGroupOnboardingStream, | ||
required Stream<TypeOfUser?> typeOfUserStream, | ||
}) { | ||
required UrlLauncherExtended urlLauncher, | ||
}) : _urlLauncher = urlLauncher { | ||
_userIdSubscription = userIdStream.listen((userId) { | ||
this.userId = userId; | ||
notifyListeners(); | ||
|
@@ -119,6 +125,34 @@ class SupportPageController extends ChangeNotifier { | |
return url; | ||
} | ||
|
||
Future<void> sendEmailToFreeSupport() async { | ||
await _openEmailApp( | ||
email: freeSupportEmail, | ||
subject: 'Meine Anfrage', | ||
); | ||
} | ||
|
||
Future<void> sendEmailToPlusSupport() async { | ||
await _openEmailApp( | ||
email: plusSupportEmail, | ||
subject: '[💎 Plus Support] Meine Anfrage', | ||
); | ||
} | ||
|
||
Future<void> _openEmailApp({ | ||
required String email, | ||
|
||
/// The subject of the email. | ||
/// | ||
/// The user ID is appended to the subject if it's not `null`. | ||
required String subject, | ||
}) async { | ||
if (userId != null) { | ||
subject += ' [User-ID: $userId]'; | ||
} | ||
await _urlLauncher.tryLaunchMailOrThrow(email, subject: subject); | ||
} | ||
|
||
bool _isPrivateAppleEmail(String email) { | ||
return email.endsWith('@privaterelay.appleid.com') || email == '-'; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,11 +8,23 @@ | |
|
||
import 'package:common_domain_models/common_domain_models.dart'; | ||
import 'package:flutter_test/flutter_test.dart'; | ||
import 'package:mockito/annotations.dart'; | ||
import 'package:mockito/mockito.dart'; | ||
import 'package:sharezone/support/support_page_controller.dart'; | ||
import 'package:url_launcher_extended/url_launcher_extended.dart'; | ||
import 'package:user/user.dart'; | ||
|
||
import 'support_page_controller_test.mocks.dart'; | ||
|
||
@GenerateNiceMocks([MockSpec<UrlLauncherExtended>()]) | ||
void main() { | ||
group(SupportPageController, () { | ||
late MockUrlLauncherExtended urlLauncher; | ||
|
||
setUp(() { | ||
urlLauncher = MockUrlLauncherExtended(); | ||
}); | ||
|
||
group('getVideoCallAppointmentsUnencodedUrlWithPrefills()', () { | ||
test('throws $UserNotAuthenticatedException when user Id is null', | ||
() async { | ||
|
@@ -23,6 +35,7 @@ void main() { | |
hasPlusSupportUnlockedStream: Stream.value(false), | ||
isUserInGroupOnboardingStream: Stream.value(false), | ||
typeOfUserStream: Stream.value(null), | ||
urlLauncher: urlLauncher, | ||
); | ||
|
||
// Workaround to wait for stream subscription in constructor. | ||
|
@@ -42,6 +55,7 @@ void main() { | |
hasPlusSupportUnlockedStream: Stream.value(false), | ||
isUserInGroupOnboardingStream: Stream.value(false), | ||
typeOfUserStream: Stream.value(null), | ||
urlLauncher: urlLauncher, | ||
); | ||
|
||
// Workaround to wait for stream subscription in constructor. | ||
|
@@ -63,6 +77,7 @@ void main() { | |
hasPlusSupportUnlockedStream: Stream.value(true), | ||
isUserInGroupOnboardingStream: Stream.value(false), | ||
typeOfUserStream: Stream.value(TypeOfUser.parent), | ||
urlLauncher: urlLauncher, | ||
); | ||
|
||
// Workaround to wait for stream subscription in constructor. | ||
|
@@ -82,6 +97,7 @@ void main() { | |
hasPlusSupportUnlockedStream: Stream.value(true), | ||
isUserInGroupOnboardingStream: Stream.value(false), | ||
typeOfUserStream: Stream.value(TypeOfUser.teacher), | ||
urlLauncher: urlLauncher, | ||
); | ||
|
||
// Workaround to wait for stream subscription in constructor. | ||
|
@@ -101,6 +117,7 @@ void main() { | |
hasPlusSupportUnlockedStream: Stream.value(false), | ||
isUserInGroupOnboardingStream: Stream.value(false), | ||
typeOfUserStream: Stream.value(TypeOfUser.teacher), | ||
urlLauncher: urlLauncher, | ||
); | ||
|
||
// Workaround to wait for stream subscription in constructor. | ||
|
@@ -120,6 +137,7 @@ void main() { | |
hasPlusSupportUnlockedStream: Stream.value(true), | ||
isUserInGroupOnboardingStream: Stream.value(false), | ||
typeOfUserStream: Stream.value(TypeOfUser.student), | ||
urlLauncher: urlLauncher, | ||
); | ||
|
||
// Workaround to wait for stream subscription in constructor. | ||
|
@@ -131,5 +149,55 @@ void main() { | |
); | ||
}); | ||
}); | ||
|
||
group('open email app', () { | ||
test('free user', () async { | ||
final controller = SupportPageController( | ||
userIdStream: Stream.value(const UserId('userId123')), | ||
userNameStream: Stream.value('My Cool Name'), | ||
userEmailStream: Stream.value('[email protected]'), | ||
hasPlusSupportUnlockedStream: Stream.value(false), | ||
isUserInGroupOnboardingStream: Stream.value(false), | ||
typeOfUserStream: Stream.value(TypeOfUser.student), | ||
urlLauncher: urlLauncher, | ||
); | ||
|
||
// Workaround to wait for stream subscription in constructor. | ||
await Future.delayed(Duration.zero); | ||
|
||
await controller.sendEmailToFreeSupport(); | ||
|
||
verify( | ||
urlLauncher.tryLaunchMailOrThrow( | ||
freeSupportEmail, | ||
subject: "Meine Anfrage [User-ID: userId123]", | ||
), | ||
); | ||
}); | ||
|
||
test('plus user', () async { | ||
final controller = SupportPageController( | ||
userIdStream: Stream.value(const UserId('userId123')), | ||
userNameStream: Stream.value('My Cool Name'), | ||
userEmailStream: Stream.value('[email protected]'), | ||
hasPlusSupportUnlockedStream: Stream.value(true), | ||
isUserInGroupOnboardingStream: Stream.value(false), | ||
typeOfUserStream: Stream.value(TypeOfUser.student), | ||
urlLauncher: urlLauncher, | ||
); | ||
|
||
// Workaround to wait for stream subscription in constructor. | ||
await Future.delayed(Duration.zero); | ||
|
||
await controller.sendEmailToPlusSupport(); | ||
|
||
verify( | ||
urlLauncher.tryLaunchMailOrThrow( | ||
plusSupportEmail, | ||
subject: "[💎 Plus Support] Meine Anfrage [User-ID: userId123]", | ||
), | ||
); | ||
}); | ||
}); | ||
}); | ||
} |
102 changes: 102 additions & 0 deletions
102
app/test/settings/support/support_page_controller_test.mocks.dart
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.