ente/lib/utils/email_util.dart

177 lines
4.6 KiB
Dart
Raw Normal View History

2021-06-12 10:33:24 +00:00
import 'dart:io';
import 'package:archive/archive_io.dart';
2021-05-29 22:48:23 +00:00
import 'package:email_validator/email_validator.dart';
2021-08-09 14:12:42 +00:00
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
2021-06-12 10:33:24 +00:00
import 'package:flutter_email_sender/flutter_email_sender.dart';
2022-03-05 21:22:45 +00:00
import 'package:logging/logging.dart';
2021-06-12 10:33:24 +00:00
import 'package:path_provider/path_provider.dart';
2022-06-23 04:12:58 +00:00
import 'package:photos/core/configuration.dart';
import 'package:photos/core/error-reporting/super_logging.dart';
import 'package:photos/ente_theme_data.dart';
import 'package:photos/ui/common/dialogs.dart';
2021-08-09 14:35:17 +00:00
import 'package:photos/ui/log_file_viewer.dart';
2021-06-12 10:33:24 +00:00
import 'package:photos/utils/dialog_util.dart';
2021-10-05 04:56:48 +00:00
import 'package:share_plus/share_plus.dart';
2021-05-29 22:48:23 +00:00
2022-03-05 21:22:45 +00:00
final Logger _logger = Logger('email_util');
2020-10-09 21:45:07 +00:00
bool isValidEmail(String email) {
2021-05-29 22:48:23 +00:00
return EmailValidator.validate(email);
2020-10-09 21:45:07 +00:00
}
2021-06-12 10:33:24 +00:00
Future<void> sendLogs(
BuildContext context,
2021-08-09 14:12:42 +00:00
String title,
String toEmail, {
Function postShare,
2021-06-12 10:33:24 +00:00
String subject,
String body,
2021-08-09 14:12:42 +00:00
}) async {
2021-08-09 14:35:17 +00:00
final List<Widget> actions = [
TextButton(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Icon(
Icons.feed_outlined,
color: Theme.of(context).iconTheme.color.withOpacity(0.85),
2021-08-09 14:35:17 +00:00
),
Padding(padding: EdgeInsets.all(4)),
2021-08-09 14:12:42 +00:00
Text(
2022-06-06 13:42:27 +00:00
"View logs",
2021-08-09 14:12:42 +00:00
style: TextStyle(
2022-06-11 08:23:52 +00:00
color: Theme.of(context)
.colorScheme
.defaultTextColor
.withOpacity(0.85),
),
2021-08-09 14:12:42 +00:00
),
],
),
2021-08-09 14:35:17 +00:00
onPressed: () async {
showDialog(
context: context,
builder: (BuildContext context) {
return LogFileViewer(SuperLogging.logFile);
},
barrierColor: Colors.black87,
barrierDismissible: false,
);
},
2021-08-09 14:12:42 +00:00
),
2021-08-09 14:35:17 +00:00
TextButton(
child: Text(
title,
style: TextStyle(
color: Theme.of(context).buttonColor,
),
),
onPressed: () async {
Navigator.of(context, rootNavigator: true).pop('dialog');
await _sendLogs(context, toEmail, subject, body);
if (postShare != null) {
postShare();
}
},
),
];
final List<Widget> content = [];
content.addAll(
[
Text(
2022-06-23 07:25:45 +00:00
"This will send across logs to help us debug your issue. Please note that file names will be included to help track issues with specific files.",
2021-08-09 14:35:17 +00:00
style: TextStyle(
height: 1.5,
fontSize: 16,
2021-08-09 14:12:42 +00:00
),
2021-08-09 14:35:17 +00:00
),
Padding(padding: EdgeInsets.all(12)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: actions,
2021-08-09 14:12:42 +00:00
),
],
);
2021-08-09 14:35:17 +00:00
final confirmation = AlertDialog(
title: Text(
title,
style: TextStyle(
fontSize: 18,
),
),
content: SingleChildScrollView(
child: ListBody(
children: content,
),
),
);
2021-08-09 14:12:42 +00:00
showDialog(
context: context,
builder: (_) {
return confirmation;
},
);
}
Future<void> _sendLogs(
2022-06-11 08:23:52 +00:00
BuildContext context,
String toEmail,
String subject,
String body,
) async {
String zipFilePath = await getZippedLogsFile(context);
2021-06-12 10:33:24 +00:00
final Email email = Email(
recipients: [toEmail],
subject: subject,
body: body,
attachmentPaths: [zipFilePath],
isHTML: false,
);
try {
await FlutterEmailSender.send(email);
2022-03-05 21:22:45 +00:00
} catch (e, s) {
_logger.severe('email sender failed', e, s);
await shareLogs(context, toEmail, zipFilePath);
}
}
Future<String> getZippedLogsFile(BuildContext context) async {
2022-06-06 13:42:27 +00:00
final dialog = createProgressDialog(context, "Preparing logs...");
await dialog.show();
2022-06-23 04:12:58 +00:00
final logsPath = (await getApplicationSupportDirectory()).path;
final logsDirectory = Directory(logsPath + "/logs");
final tempPath = (await getTemporaryDirectory()).path;
final zipFilePath =
tempPath + "/logs-${Configuration.instance.getUserID() ?? 0}.zip";
var encoder = ZipFileEncoder();
encoder.create(zipFilePath);
encoder.addDirectory(logsDirectory);
encoder.close();
await dialog.hide();
return zipFilePath;
}
Future<void> shareLogs(
2022-06-11 08:23:52 +00:00
BuildContext context,
String toEmail,
String zipFilePath,
) async {
final result = await showChoiceDialog(
2022-06-11 08:23:52 +00:00
context,
"Email logs",
"Please send the logs to $toEmail",
firstAction: "Copy email",
secondAction: "Send",
);
if (result != null && result == DialogUserChoice.firstChoice) {
await Clipboard.setData(ClipboardData(text: toEmail));
2021-06-12 10:33:24 +00:00
}
final Size size = MediaQuery.of(context).size;
2022-06-11 08:23:52 +00:00
await Share.shareFiles(
[zipFilePath],
sharePositionOrigin: Rect.fromLTWH(0, 0, size.width, size.height / 2),
);
2021-06-12 10:33:24 +00:00
}