Flutter Integration
This example demonstrates how to integrate the Hubble Gift Card Store SDK in a Flutter application.
import '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;
@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) { // Handle page start }, onPageFinished: (String url) { // Handle page finish }, onWebResourceError: (WebResourceError error) { // Handle errors }, onNavigationRequest: (NavigationRequest request) { if (request.url.startsWith(baseUrl)) { return NavigationDecision.navigate; } else { _launchURL(request.url); return NavigationDecision.prevent; } }, ), ) ..addJavaScriptChannel( 'Hubble', onMessageReceived: (JavaScriptMessage message) { _handleEvent(message.message); }, ) ..loadRequest(Uri.parse(sourceUrl)); }
Future<void> _launchURL(String url) async { if (await canLaunchUrl(Uri.parse(url))) { await launchUrl(Uri.parse(url)); } else { throw 'Could not launch $url'; } }
void _handleEvent(String message) { try { final eventData = Map<String, dynamic>.from( Map<String, dynamic>.from( const JsonDecoder().convert(message), ), );
final event = eventData['event']; final properties = eventData['properties']; final action = eventData['action'];
var eventParams = { 'eventName': event, };
if (properties != null) { eventParams.addAll(Map<String, dynamic>.from(properties)); }
if (action == 'close') { Navigator.of(context).pop(); }
_logEvent(event, eventParams); } catch (e) { print('Error handling event: $e'); } }
void _logEvent(String eventType, Map<String, dynamic> eventParams) { // your implementation of sending events to analytics print('Event Type: $eventType'); print('Event Params: $eventParams'); }
@override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async { if (await _controller.canGoBack()) { await _controller.goBack(); return false; } return true; }, child: Scaffold( body: SafeArea( child: WebViewWidget(controller: _controller), ), ), ); }}