Flutter Integration
This example demonstrates how to integrate the Hubble Gift Card Store SDK in a Flutter application.
import 'dart:convert'; // Required for jsonDecodeimport 'package:flutter/material.dart';import 'package:webview_flutter/webview_flutter.dart';import 'package:url_launcher/url_launcher.dart';
class HubbleWebView extends StatefulWidget {  const HubbleWebView({Key? key}) : super(key: key);
  @override  State<HubbleWebView> createState() => _HubbleWebViewState();}
class _HubbleWebViewState extends State<HubbleWebView> {  late final WebViewController _controller;  bool _isWebViewReady = false;
  @override  void initState() {    super.initState();    _initWebView();  }
  void _initWebView() {    final params = {      'authToken': 'authToken', // your auth token      'clientId': 'id_given_by_hubble',      'clientSecret': 'secret_given_by_hubble',      'env': 'debug',      'wrapPlt': 'flutter',      // 'page': 'transactions', // optional initial page to load, default is home    };
    final baseUrl = 'https://vouchers.dev.myhubble.money/classic';    // prod baseUrl is https://vouchers.myhubble.money/classic    final sourceUrl = '$baseUrl?clientId=${params['clientId']}&clientSecret=${params['clientSecret']}&token=${params['authToken']}&wrap-plt=${params['wrapPlt']}&env=${params['env']}&page=${params['page']}';
    _controller = WebViewController()      ..setJavaScriptMode(JavaScriptMode.unrestricted)      ..setBackgroundColor(Colors.white)      ..setNavigationDelegate(        NavigationDelegate(          onPageStarted: (String url) {            print('Page started loading: $url');          },          onPageFinished: (String url) {            setState(() {              _isWebViewReady = true;            });            print('Page finished loading: $url');          },          onWebResourceError: (WebResourceError error) {            print('Web resource error: ${error.description}');          },          onNavigationRequest: (NavigationRequest request) {            if (request.url.startsWith(baseUrl)) {              return NavigationDecision.navigate;            } else {              _launchURL(request.url);              return NavigationDecision.prevent;            }          },        ),      )      ..addJavaScriptChannel(        'FlutterHost',        onMessageReceived: (JavaScriptMessage message) {          _handleEvent(message.message);        },      )      ..loadRequest(Uri.parse(sourceUrl));  }
  Future<void> _launchURL(String url) async {    final uri = Uri.parse(url);    if (await canLaunchUrl(uri)) {      await launchUrl(uri, mode: LaunchMode.externalApplication);    } else {      print('Could not launch $url');    }  }
  void _handleEvent(String jsonString) {    try {      final eventData = jsonDecode(jsonString) as Map<String, dynamic>;      final String? action = eventData['action'] as String?;
      // Check for the 'close' action first for an early exit.      if (action == 'close') {        print("Received 'close' action from WebView. Popping screen.");        Navigator.of(context).pop();        return;      }
      // If it's not a close action, proceed with logging other events.      final String? event = eventData['event'] as String?;      final Map<String, dynamic>? properties = eventData['properties'] as Map<String, dynamic>?;
      if (event != null) {        _logEvent(event, properties ?? {});      }
    } catch (e) {      print('Error handling event from WebView: $e');      print('Received message: $jsonString');    }  }
  void _logEvent(String eventType, Map<String, dynamic> eventParams) {    // Your implementation of sending events to analytics    print('Analytics Event Type: $eventType');    print('Analytics Event Params: $eventParams');  }
  @override  Widget build(BuildContext context) {    return WillPopScope(      onWillPop: () async {        if (!_isWebViewReady) return true;
        if (await _controller.canGoBack()) {          await _controller.goBack();          return false;        }        return true;      },      child: Scaffold(        body: SafeArea(          child: WebViewWidget(controller: _controller),        ),      ),    );  }} 
 