2

In flutter, we use platform channels that allows us to call platform-specific APIs whether available in Kotlin or Java code on Android, or in Swift or Objective-C code on iOS.

How to achieve the same with web in flutter ? How can one use a npm package and write some javascript code and send the result to flutter? Is this even possible ? There is official docs for writing platform specific code for Android and iOS, but I couldn't find any docs for writing platform specific code for web.

Also, I tried using the js package. If this is the one that has to be used for this case, how to use it ?

1 Answers1

0

This is what I do to display Hubspot chat on Flutter Web. I have a folder for Hubspot with:

  • index.html
  • script.js
  • style.css

Then a Flutter Widget with webview_flutter_plus plugin:

class HubspotWebview extends StatefulWidget {
  @override
  _HubspotWebviewState createState() => _HubspotWebviewState();
}

class _HubspotWebviewState extends State<HubspotWebview> {
  final _javascriptChannels = Set<JavascriptChannel>();
  bool loading = true;

  @override
  void initState() {
    super.initState();
    _javascriptChannels.add(JavascriptChannel(
        onMessageReceived: (JavascriptMessage message) {
          debugPrint('message: ' + message.message);
          _toggleLoading();
        },
        name: 'Loading'));
  }

  @override
  Widget build(BuildContext context) {
    final path = '${kIsWeb ? 'assets/' : ''}assets/hubspot_web_page/index.html';
    final key = 'web_bot_key';
    if (kIsWeb) {
      ui.platformViewRegistry.registerViewFactory(
          key,
              (int viewId) => IFrameElement()
            ..width = '640'
            ..height = '360'
            ..src = path
            ..style.border = 'none'
            ..onLoadedData.listen((event) {
              _toggleLoading();
            }));
    }
    return Scaffold(
      appBar: new AppBar(
          backgroundColor: MyColors.blue_business,
          title: MyText.subtitle(
            getText('business_help_chat', backUpText: 'Help Chat'),
            color: MyColors.white_rice,
          )),
      body: Stack(
        children: [
          kIsWeb
              ? HtmlElementView(viewType: key)
              : WebViewPlus(
            javascriptMode: JavascriptMode.unrestricted,
            initialUrl: path,
            javascriptChannels: _javascriptChannels,
          ),
          if (loading)
            Center(child: CircularProgressIndicator()),
        ],
      ),
    );
  }

  void _toggleLoading() => setState(() => loading = !loading);
}

On Javascript file Loading.postMessage('') triggers toggleLoading() on Flutter:

  function onConversationsAPIReady() {
    window.hsConversationsSettings = {
      inlineEmbedSelector: '#hubspot-conversations-inline-parent',
      enableWidgetCookieBanner: true,
      disableAttachment: true
    };
    window.history.pushState({}, 'bot', '?bot=true');
    window.HubSpotConversations.widget.refresh({openToNewThread: true});
    Loading.postMessage('');
  }

  if (window.HubSpotConversations) {
    onConversationsAPIReady();
  } else {
    window.hsConversationsOnReady = [onConversationsAPIReady];
  }
Luca Oropallo
  • 474
  • 4
  • 12