Skip to content

Commit 6db6bb2

Browse files
author
Mihail Varbanov
committed
Added functionality to share test result document (#591).
1 parent 6abbb5f commit 6db6bb2

File tree

5 files changed

+380
-11
lines changed

5 files changed

+380
-11
lines changed

assets/test.result.html

+291
Large diffs are not rendered by default.

images/2.0x/icon-share.png

1.58 KB
Loading

images/3.0x/icon-share.png

1.41 KB
Loading

images/icon-share.png

1.2 KB
Loading

lib/ui/health/HealthHistoryPanel.dart

+89-11
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
* limitations under the License.
1515
*/
1616

17+
import 'dart:io';
18+
1719
import 'package:flutter/foundation.dart';
1820
import 'package:flutter/material.dart';
1921
import 'package:flutter/semantics.dart';
@@ -33,6 +35,10 @@ import 'package:illinois/ui/widgets/PopupDialog.dart';
3335
import 'package:illinois/ui/widgets/RoundedButton.dart';
3436
import 'package:illinois/utils/Utils.dart';
3537
import 'package:url_launcher/url_launcher.dart';
38+
import 'package:flutter/services.dart' show rootBundle;
39+
import 'package:flutter_html_to_pdf/flutter_html_to_pdf.dart';
40+
import 'package:path_provider/path_provider.dart';
41+
import 'package:share/share.dart';
3642

3743
class HealthHistoryPanel extends StatefulWidget {
3844
@override
@@ -433,6 +439,7 @@ class _HealthHistoryEntryState extends State<_HealthHistoryEntry> with SingleTic
433439
bool _expanded = false;
434440
AnimationController _controller;
435441

442+
bool _sharing = false;
436443
bool _isLoadingLocation = false;
437444

438445
@override
@@ -472,10 +479,7 @@ class _HealthHistoryEntryState extends State<_HealthHistoryEntry> with SingleTic
472479

473480
content.add(Container(height: 16,));
474481

475-
return Container(
476-
padding: EdgeInsets.symmetric(),
477-
child: Column(children: content,),
478-
);
482+
return Column(children: content,);
479483
}
480484

481485
Widget _buildCommonInfo(){
@@ -566,13 +570,16 @@ class _HealthHistoryEntryState extends State<_HealthHistoryEntry> with SingleTic
566570
}
567571

568572
return Semantics(sortKey: OrdinalSortKey(1), container: true, child:
569-
Container(color: Styles().colors.white, padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), child:
570-
Row(children: <Widget>[
571-
Expanded(child:
572-
Column(crossAxisAlignment: CrossAxisAlignment.start, children: contentList,)
573-
),
574-
]),
575-
),
573+
Stack(children: [
574+
Container(color: Styles().colors.white, padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), child:
575+
Row(children: <Widget>[
576+
Expanded(child:
577+
Column(crossAxisAlignment: CrossAxisAlignment.start, children: contentList,),
578+
),
579+
]),
580+
),
581+
_buildShareButton(),
582+
]),
576583
);
577584
}
578585

@@ -727,6 +734,33 @@ class _HealthHistoryEntryState extends State<_HealthHistoryEntry> with SingleTic
727734
);
728735
}
729736

737+
Widget _buildShareButton() {
738+
return Visibility(visible: (widget.historyEntry.isTest == true), child:
739+
Align(alignment: Alignment.topRight, child:
740+
Semantics (button: true, label: "Share", child:
741+
GestureDetector(onTap: () { _onTapShare(); }, child:
742+
Container(width: 36, height: 36, child:
743+
Stack(children: [
744+
Align(alignment: Alignment.center, child:
745+
Semantics(excludeSemantics: true, child:
746+
Image.asset('images/icon-share.png')
747+
),
748+
),
749+
Visibility(visible: _sharing, child:
750+
Align(alignment: Alignment.center, child:
751+
Container(width: 16, height: 16, child:
752+
CircularProgressIndicator(valueColor: AlwaysStoppedAnimation<Color>(Styles().colors.fillColorSecondary), strokeWidth: 2,)
753+
),
754+
),
755+
),
756+
],),
757+
),
758+
),
759+
),
760+
),
761+
);
762+
}
763+
730764
void _onTapLocation() {
731765
Analytics().logSelect(target: widget.historyEntry?.blob?.locationId);
732766
String locationId = widget.historyEntry?.blob?.locationId;
@@ -787,4 +821,48 @@ class _HealthHistoryEntryState extends State<_HealthHistoryEntry> with SingleTic
787821
Analytics.instance.logSelect(target: "Close Disclaimer");
788822
Navigator.of(context).pop();
789823
}
824+
825+
void _onTapShare() {
826+
if (!_sharing) {
827+
setState(() {
828+
_sharing = true;
829+
});
830+
_createTestResultPdf().then((File pdfFile) {
831+
if (mounted) {
832+
setState(() {
833+
_sharing = false;
834+
});
835+
if (pdfFile != null) {
836+
String subject = "${widget?.historyEntry?.blob?.testType} test result";
837+
String text = "${widget?.historyEntry?.blob?.testType} test result";
838+
String mimeType = "application/pdf";
839+
String pdfFilePath = pdfFile.path;
840+
try {
841+
Share.shareFiles([pdfFilePath], subject: subject, text: text, mimeTypes: [mimeType]);
842+
}
843+
catch(e) {
844+
print(e?.toString());
845+
AppAlert.showDialogResult(context, "Unable to share test result document");
846+
}
847+
}
848+
else {
849+
AppAlert.showDialogResult(context, "Unable to prepare test result document");
850+
}
851+
}
852+
});
853+
}
854+
}
855+
856+
Future<File> _createTestResultPdf() async {
857+
String htmlSource = await rootBundle.loadString('assets/test.result.html');
858+
859+
Directory appDocDir = await getTemporaryDirectory();
860+
String targetPath = appDocDir.path;
861+
String targetFileName = "test-result";
862+
863+
try { return await FlutterHtmlToPdf.convertFromHtmlContent(htmlSource, targetPath, targetFileName); }
864+
catch(e) { print(e?.toString()); }
865+
return null;
866+
}
867+
790868
}

0 commit comments

Comments
 (0)