diff --git a/lib/app.dart b/lib/app.dart index fd93fb23c..7eb9cc7a6 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -151,6 +151,12 @@ class _EnteAppState extends State with WidgetsBindingObserver { ); } + @override + void dispose() { + WidgetsBinding.instance.removeObserver(this); + super.dispose(); + } + @override void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.resumed) { diff --git a/lib/ui/common/report_bug_popup.dart b/lib/ui/common/report_bug_popup.dart index a827f339c..84236a2af 100644 --- a/lib/ui/common/report_bug_popup.dart +++ b/lib/ui/common/report_bug_popup.dart @@ -1,29 +1,27 @@ - import 'package:flutter/material.dart'; import 'package:photos/utils/email_util.dart'; PopupMenuButton reportBugPopupMenu(BuildContext context) { - return PopupMenuButton( - itemBuilder: (context) { - final List items = []; - items.add( - PopupMenuItem( - value: 1, - child: Row( - children: const [ - Text("contact support"), - ], - ), + return PopupMenuButton( + itemBuilder: (context) { + final List items = []; + items.add( + PopupMenuItem( + value: 1, + child: Row( + children: const [ + Text("contact support"), + ], ), - ); - return items; - }, - onSelected: (value) async { - if (value == 1) { - await sendLogs(context, "contact support", "support@ente.io", postShare: () { - - }); - } - }, - ); - } \ No newline at end of file + ), + ); + return items; + }, + onSelected: (value) async { + if (value == 1) { + await sendLogs(context, "contact support", "support@ente.io", + postShare: () {}); + } + }, + ); +} diff --git a/lib/ui/settings/info_section_widget.dart b/lib/ui/settings/info_section_widget.dart index 509727711..32ca8130b 100644 --- a/lib/ui/settings/info_section_widget.dart +++ b/lib/ui/settings/info_section_widget.dart @@ -1,5 +1,3 @@ -import 'dart:io'; - import 'package:flutter/material.dart'; import 'package:photos/services/update_service.dart'; import 'package:photos/ui/app_update_dialog.dart'; @@ -69,46 +67,38 @@ class InfoSectionWidget extends StatelessWidget { child: SettingsTextItem(text: "source code", icon: Icons.navigate_next), ), - Divider(height: 4), UpdateService.instance.isIndependent() - ? GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () async { - final dialog = createProgressDialog(context, "checking..."); - await dialog.show(); - final shouldUpdate = - await UpdateService.instance.shouldUpdate(); - await dialog.hide(); - if (shouldUpdate) { - showDialog( - context: context, - builder: (BuildContext context) { - return AppUpdateDialog( - UpdateService.instance.getLatestVersionInfo()); - }, - barrierColor: Colors.black.withOpacity(0.85), - ); - } else { - showToast("you are on the latest version"); - } - }, - child: SettingsTextItem( - text: "check for updates", icon: Icons.navigate_next), + ? Column( + children: [ + Divider(height: 4), + GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () async { + final dialog = + createProgressDialog(context, "checking..."); + await dialog.show(); + final shouldUpdate = + await UpdateService.instance.shouldUpdate(); + await dialog.hide(); + if (shouldUpdate) { + showDialog( + context: context, + builder: (BuildContext context) { + return AppUpdateDialog( + UpdateService.instance.getLatestVersionInfo()); + }, + barrierColor: Colors.black.withOpacity(0.85), + ); + } else { + showToast("you are on the latest version"); + } + }, + child: SettingsTextItem( + text: "check for updates", icon: Icons.navigate_next), + ), + ], ) - : GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () { - if (Platform.isAndroid) { - launch( - "https://play.google.com/store/apps/details?id=io.ente.photos"); - } else { - launch( - "https://apps.apple.com/in/app/ente-photos/id1542026904"); - } - }, - child: SettingsTextItem( - text: "store rating", icon: Icons.navigate_next), - ), + : Container(), ], ); } diff --git a/lib/ui/settings/social_section_widget.dart b/lib/ui/settings/social_section_widget.dart new file mode 100644 index 000000000..be94b8419 --- /dev/null +++ b/lib/ui/settings/social_section_widget.dart @@ -0,0 +1,65 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:photos/services/update_service.dart'; +import 'package:photos/ui/settings/settings_section_title.dart'; +import 'package:photos/ui/settings/settings_text_item.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class SocialSectionWidget extends StatelessWidget { + const SocialSectionWidget({Key key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + SettingsSectionTitle("social"), + Padding(padding: EdgeInsets.all(4)), + GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () { + launch("https://twitter.com/enteio"); + }, + child: SettingsTextItem(text: "twitter", icon: Icons.navigate_next), + ), + Divider(height: 4), + GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () { + launch("https://discord.gg/uRqua3jSr5"); + }, + child: SettingsTextItem(text: "discord", icon: Icons.navigate_next), + ), + Divider(height: 4), + GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () { + launch("https://reddit.com/r/enteio"); + }, + child: SettingsTextItem(text: "reddit", icon: Icons.navigate_next), + ), + !UpdateService.instance.isIndependent() + ? Column( + children: [ + Divider(height: 4), + GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () { + if (Platform.isAndroid) { + launch( + "https://play.google.com/store/apps/details?id=io.ente.photos"); + } else { + launch( + "https://apps.apple.com/in/app/ente-photos/id1542026904"); + } + }, + child: SettingsTextItem( + text: "rate us! ✨", icon: Icons.navigate_next), + ), + ], + ) + : Container(), + ], + ); + } +} diff --git a/lib/ui/settings/support_section_widget.dart b/lib/ui/settings/support_section_widget.dart index 43e23416f..f11123b60 100644 --- a/lib/ui/settings/support_section_widget.dart +++ b/lib/ui/settings/support_section_widget.dart @@ -56,14 +56,6 @@ class SupportSectionWidget extends StatelessWidget { child: SettingsTextItem(text: "roadmap", icon: Icons.navigate_next), ), Divider(height: 4), - GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () { - launch("https://reddit.com/r/enteio"); - }, - child: SettingsTextItem(text: "community", icon: Icons.navigate_next), - ), - Divider(height: 4), GestureDetector( behavior: HitTestBehavior.translucent, onTap: () async { diff --git a/lib/ui/settings_page.dart b/lib/ui/settings_page.dart index bb9006f89..e747a61db 100644 --- a/lib/ui/settings_page.dart +++ b/lib/ui/settings_page.dart @@ -10,6 +10,7 @@ import 'package:photos/ui/settings/debug_section_widget.dart'; import 'package:photos/ui/settings/details_section_widget.dart'; import 'package:photos/ui/settings/info_section_widget.dart'; import 'package:photos/ui/settings/security_section_widget.dart'; +import 'package:photos/ui/settings/social_section_widget.dart'; import 'package:photos/ui/settings/support_section_widget.dart'; class SettingsPage extends StatelessWidget { @@ -43,6 +44,8 @@ class SettingsPage extends StatelessWidget { Padding(padding: EdgeInsets.all(12)), SupportSectionWidget(), Padding(padding: EdgeInsets.all(12)), + SocialSectionWidget(), + Padding(padding: EdgeInsets.all(12)), InfoSectionWidget(), ]); if (hasLoggedIn) { diff --git a/lib/utils/email_util.dart b/lib/utils/email_util.dart index 8819b4a7b..069bb7cc9 100644 --- a/lib/utils/email_util.dart +++ b/lib/utils/email_util.dart @@ -3,16 +3,19 @@ import 'dart:io'; import 'package:archive/archive_io.dart'; import 'package:email_validator/email_validator.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_email_sender/flutter_email_sender.dart'; import 'package:logging/logging.dart'; import 'package:path_provider/path_provider.dart'; +import 'package:photos/ui/common/dialogs.dart'; import 'package:photos/ui/log_file_viewer.dart'; import 'package:photos/utils/dialog_util.dart'; import 'package:share_plus/share_plus.dart'; import 'package:super_logging/super_logging.dart'; final Logger _logger = Logger('email_util'); + bool isValidEmail(String email) { return EmailValidator.validate(email); } @@ -133,6 +136,12 @@ Future _sendLogs( await FlutterEmailSender.send(email); } catch (e, s) { _logger.severe('email sender failed', e, s); + final result = await showChoiceDialog( + context, "email logs", "please send the logs to $toEmail", + firstAction: "copy email", secondAction: "ok"); + if (result != null && result == DialogUserChoice.firstChoice) { + await Clipboard.setData(ClipboardData(text: toEmail)); + } await Share.shareFiles([zipFilePath]); } }