diff --git a/lib/ui/views/ib/builders/ib_webview_builder.dart b/lib/ui/views/ib/builders/ib_webview_builder.dart new file mode 100644 index 00000000..75a05dbf --- /dev/null +++ b/lib/ui/views/ib/builders/ib_webview_builder.dart @@ -0,0 +1,37 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_html/flutter_html.dart'; +import 'package:flutter_html/html_parser.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; +import 'package:webview_flutter/webview_flutter.dart'; +import 'package:markdown/markdown.dart' as md; + +class IbWebViewBuilder extends MarkdownElementBuilder { + final BuildContext context; + + IbWebViewBuilder({this.context}); + + @override + Widget visitElementAfter(md.Element element, TextStyle preferredStyle) { + var textContent = element.textContent; + + return Html( + data: textContent, + customRender: { + 'iframe': (RenderContext context, Widget child, attributes, _) { + final width = MediaQuery.of(context.buildContext).size.width; + final height = (width * 9) / 16; + + return SizedBox( + width: width, + height: height, + child: WebView( + initialUrl: attributes['src'], + javascriptMode: JavascriptMode.unrestricted, + initialMediaPlaybackPolicy: AutoMediaPlaybackPolicy.always_allow, + ), + ); + }, + }, + ); + } +} diff --git a/lib/ui/views/ib/ib_page_view.dart b/lib/ui/views/ib/ib_page_view.dart index 44016b42..ea8c0ed7 100644 --- a/lib/ui/views/ib/ib_page_view.dart +++ b/lib/ui/views/ib/ib_page_view.dart @@ -7,6 +7,8 @@ import 'package:mobile_app/models/ib/ib_chapter.dart'; import 'package:mobile_app/models/ib/ib_content.dart'; import 'package:mobile_app/models/ib/ib_page_data.dart'; import 'package:mobile_app/ui/views/base_view.dart'; +import 'package:mobile_app/ui/views/ib/builders/ib_webview_builder.dart'; +import 'package:mobile_app/ui/views/ib/syntaxes/ib_embed_syntax.dart'; import 'package:mobile_app/ui/views/ib/syntaxes/ib_filter_syntax.dart'; import 'package:mobile_app/ui/views/ib/syntaxes/ib_md_tag_syntax.dart'; import 'package:mobile_app/viewmodels/ib/ib_page_viewmodel.dart'; @@ -66,8 +68,12 @@ class _IbPageViewState extends State { return MarkdownBody( data: data.content, selectable: true, + blockBuilders: { + 'iframe': IbWebViewBuilder(context: context), + }, extensionSet: md.ExtensionSet( [ + IbEmbedSyntax(), IbFilterSyntax(), IbMdTagSyntax(), ...md.ExtensionSet.gitHubFlavored.blockSyntaxes diff --git a/lib/ui/views/ib/syntaxes/ib_embed_syntax.dart b/lib/ui/views/ib/syntaxes/ib_embed_syntax.dart new file mode 100644 index 00000000..7cb5ea00 --- /dev/null +++ b/lib/ui/views/ib/syntaxes/ib_embed_syntax.dart @@ -0,0 +1,16 @@ +import 'package:markdown/markdown.dart' as md; + +class IbEmbedSyntax extends md.BlockSyntax { + IbEmbedSyntax() : super(); + + @override + md.Node parse(md.BlockParser parser) { + var text = parser.current; + parser.advance(); + + return md.Element.text('iframe', text); + } + + @override + RegExp get pattern => RegExp(r'^.+<\/iframe>'); +} diff --git a/pubspec.yaml b/pubspec.yaml index 733e5656..823fbb9c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -26,11 +26,11 @@ dependencies: cupertino_icons: ^1.0.2 datetime_picker_formfield: ^2.0.0 flutter_facebook_auth: ^3.3.2 - flutter_html: ^1.0.2 + flutter_html: ^1.3.0 flutter_icons: ^1.1.0 flutter_keyboard_visibility: ^5.0.0 flutter_summernote: ^0.2.3 - flutter_svg: ^0.19.3 + flutter_svg: ^0.20.0-nullsafety.3 flutter_typeahead: ^3.0.0-nullsafety.0 get: ^3.26.0 get_it: ^6.0.0 @@ -48,12 +48,14 @@ dependencies: timeago: ^3.0.2 transparent_image: ^1.0.0 url_launcher: ^6.0.2 - flutter_markdown: ^0.5.2 + flutter_markdown: + git: + url: git://github.com/manjotsidhu/packages.git + path: packages/flutter_markdown dev_dependencies: flutter_test: sdk: flutter - flutter_launcher_icons: ^0.8.1 pedantic: ^1.9.0 dependency_overrides: