-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fixup! TF-3267 Implement HTML attachment preview
- Loading branch information
1 parent
32e7f9e
commit 56fb1a9
Showing
5 changed files
with
188 additions
and
73 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import 'dart:convert'; | ||
|
||
import 'package:core/domain/exceptions/string_exception.dart'; | ||
import 'package:core/utils/string_convert.dart'; | ||
import 'package:flutter_test/flutter_test.dart'; | ||
|
||
void main() { | ||
group('string convert test:', () { | ||
const testText = 'Hello'; | ||
test( | ||
'should use utf8 decoder ' | ||
'when isHtml is true', | ||
() { | ||
// arrange | ||
final bytes = utf8.encode(testText); | ||
|
||
// act | ||
final result = StringConvert.decodeFromBytes(bytes, charset: null, isHtml: true); | ||
|
||
// assert | ||
expect(result, testText); | ||
}); | ||
|
||
test( | ||
'should use utf8 decoder ' | ||
'when charset contains utf-8', | ||
() { | ||
// arrange | ||
final bytes = utf8.encode(testText); | ||
|
||
// act | ||
final result = StringConvert.decodeFromBytes(bytes, charset: 'utf-8'); | ||
|
||
// assert | ||
expect(result, testText); | ||
}); | ||
|
||
test( | ||
'should use latin1 decoder ' | ||
'when charset contains latin-1', | ||
() { | ||
// arrange | ||
final bytes = latin1.encode(testText); | ||
|
||
// act | ||
final result = StringConvert.decodeFromBytes(bytes, charset: 'latin-1'); | ||
|
||
// assert | ||
expect(result, testText); | ||
}); | ||
|
||
test( | ||
'should use ascii decoder ' | ||
'when charset contains ascii', | ||
() { | ||
// arrange | ||
final bytes = ascii.encode(testText); | ||
|
||
// act | ||
final result = StringConvert.decodeFromBytes(bytes, charset: 'ascii'); | ||
|
||
// assert | ||
expect(result, testText); | ||
}); | ||
|
||
test( | ||
'should throw NullCharsetException ' | ||
'when charset is null', | ||
() { | ||
// arrange | ||
final bytes = utf8.encode(testText); | ||
|
||
// assert | ||
expect( | ||
() => StringConvert.decodeFromBytes(bytes, charset: null), | ||
throwsA(isA<NullCharsetException>()), | ||
); | ||
}); | ||
|
||
test( | ||
'should throw UnsupportedCharsetException ' | ||
'when charset is unsupported', | ||
() { | ||
// arrange | ||
final bytes = utf8.encode(testText); | ||
|
||
// assert | ||
expect( | ||
() => StringConvert.decodeFromBytes(bytes, charset: 'unsupported'), | ||
throwsA(isA<UnsupportedCharsetException>()), | ||
); | ||
}); | ||
}); | ||
} |
9 changes: 8 additions & 1 deletion
9
lib/features/email/domain/state/get_html_content_from_attachment_state.dart
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
113 changes: 55 additions & 58 deletions
113
lib/features/email/presentation/widgets/html_attachment_previewer.dart
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 |
---|---|---|
@@ -1,90 +1,87 @@ | ||
import 'dart:convert'; | ||
import 'dart:math'; | ||
|
||
import 'package:core/presentation/utils/responsive_utils.dart'; | ||
import 'package:core/presentation/utils/shims/dart_ui.dart'; | ||
import 'package:core/presentation/views/html_viewer/html_content_viewer_on_web_widget.dart'; | ||
import 'package:core/presentation/views/responsive/responsive_widget.dart'; | ||
import 'package:flutter/material.dart'; | ||
import 'package:get/get.dart'; | ||
import 'package:tmail_ui_user/features/email/presentation/widgets/pdf_viewer/top_bar_attachment_viewer.dart'; | ||
import 'package:universal_html/html.dart'; | ||
import 'package:tmail_ui_user/main/utils/app_utils.dart'; | ||
|
||
class HtmlAttachmentPreviewer extends StatefulWidget { | ||
class HtmlAttachmentPreviewer extends StatelessWidget { | ||
const HtmlAttachmentPreviewer({ | ||
super.key, | ||
required this.htmlContent, | ||
required this.title, | ||
required this.mailToClicked, | ||
required this.downloadAttachmentClicked, | ||
}); | ||
|
||
final String title; | ||
final String htmlContent; | ||
final void Function(Uri? mailToUri) mailToClicked; | ||
final VoidCallback downloadAttachmentClicked; | ||
|
||
@override | ||
State<HtmlAttachmentPreviewer> createState() => _HtmlAttachmentPreviewerState(); | ||
} | ||
|
||
class _HtmlAttachmentPreviewerState extends State<HtmlAttachmentPreviewer> { | ||
late final IFrameElement _iframeElement; | ||
late final String _viewId; | ||
|
||
@override | ||
void initState() { | ||
super.initState(); | ||
_iframeElement = IFrameElement() | ||
..srcdoc = widget.htmlContent | ||
..style.border = 'none' | ||
..style.overflow = 'hidden' | ||
..style.width = '100%' | ||
..style.height = '100%'; | ||
_viewId = _getRandString(10); | ||
|
||
platformViewRegistry.registerViewFactory(_viewId, (int viewId) => _iframeElement); | ||
} | ||
|
||
static const double _verticalMargin = 16; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Column( | ||
children: [ | ||
TopBarAttachmentViewer( | ||
title: widget.title, | ||
closeAction: () { | ||
if (!mounted) return; | ||
Get.back(); | ||
}, | ||
title: title, | ||
closeAction: Get.back, | ||
downloadAction: downloadAttachmentClicked, | ||
), | ||
Expanded( | ||
child: Center( | ||
child: ResponsiveWidget( | ||
responsiveUtils: ResponsiveUtils(), | ||
desktop: Container( | ||
width: MediaQuery.sizeOf(context).width * 0.4, | ||
color: Colors.white, | ||
margin: const EdgeInsets.symmetric(vertical: 16), | ||
child: HtmlElementView(viewType: _viewId), | ||
), | ||
tablet: Container( | ||
width: MediaQuery.sizeOf(context).width * 0.8, | ||
color: Colors.white, | ||
margin: const EdgeInsets.symmetric(vertical: 16), | ||
child: HtmlElementView(viewType: _viewId), | ||
), | ||
mobile: Container( | ||
width: MediaQuery.sizeOf(context).width, | ||
color: Colors.white, | ||
margin: const EdgeInsets.symmetric(vertical: 16), | ||
child: HtmlElementView(viewType: _viewId), | ||
), | ||
), | ||
child: LayoutBuilder( | ||
builder: (context, constraints) { | ||
return SingleChildScrollView( | ||
child: Center( | ||
child: Container( | ||
margin: const EdgeInsets.symmetric(vertical: _verticalMargin), | ||
color: Colors.white, | ||
child: ResponsiveWidget( | ||
responsiveUtils: ResponsiveUtils(), | ||
desktop: _buildHtmlViewerWith( | ||
context, | ||
width: constraints.maxWidth * 0.4, | ||
height: constraints.maxHeight - _verticalMargin * 2 | ||
), | ||
tablet: _buildHtmlViewerWith( | ||
context, | ||
width: constraints.maxWidth * 0.8, | ||
height: constraints.maxHeight - _verticalMargin * 2 | ||
), | ||
mobile: _buildHtmlViewerWith( | ||
context, | ||
width: constraints.maxWidth, | ||
height: constraints.maxHeight - _verticalMargin * 2 | ||
), | ||
), | ||
), | ||
), | ||
); | ||
} | ||
), | ||
), | ||
], | ||
); | ||
} | ||
|
||
String _getRandString(int len) { | ||
var random = Random.secure(); | ||
var values = List<int>.generate(len, (i) => random.nextInt(255)); | ||
return base64UrlEncode(values); | ||
HtmlContentViewerOnWeb _buildHtmlViewerWith( | ||
BuildContext context, { | ||
required double width, | ||
required double height, | ||
}) { | ||
return HtmlContentViewerOnWeb( | ||
contentHtml: htmlContent, | ||
widthContent: width, | ||
heightContent: height, | ||
direction: AppUtils.getCurrentDirection(context), | ||
mailtoDelegate: (uri) { | ||
Get.back(); | ||
mailToClicked(uri); | ||
}, | ||
); | ||
} | ||
} |