movable_ink_plugin 2.2.1
movable_ink_plugin: ^2.2.1 copied to clipboard
MovableInk Plugin for Flutter
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
import 'package:movable_ink_plugin/currency.dart';
import 'package:movable_ink_plugin/movable_ink_plugin.dart';
import 'package:push/push.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _resolvedURL = '';
String _pushToken = '';
static const String _pushTokenKey = 'push_token';
final _movableInkPlugin = MovableInkPlugin();
StreamSubscription<String>? streamSubscription;
VoidCallback? unsubscribeOnNewToken;
VoidCallback? unsubscribeOnNotificationTap;
@override
void initState() {
super.initState();
_loadStoredPushToken();
initMovableInkListener();
initPush();
}
Future<void> _loadStoredPushToken() async {
final prefs = await SharedPreferences.getInstance();
final storedToken = prefs.getString(_pushTokenKey);
if (storedToken != null && storedToken.isNotEmpty) {
setState(() {
_pushToken = storedToken;
});
}
}
Future<void> _savePushToken(String token) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(_pushTokenKey, token);
}
@override
void dispose() {
super.dispose();
streamSubscription?.cancel();
unsubscribeOnNewToken?.call();
unsubscribeOnNotificationTap?.call();
}
void initMovableInkListener() async {
streamSubscription = _movableInkPlugin.start().listen((String data) {
debugPrint('Resolved Deeplink: $data');
setState(() {
_resolvedURL = data;
});
}, onError: (error) {
debugPrint('start error: ${error.toString()}');
});
_movableInkPlugin.setMIU("00000000-0000-0000-0000-000000000000");
}
void initPush() async {
await Push.instance.requestPermission();
Push.instance.registerForRemoteNotifications();
unsubscribeOnNewToken = Push.instance.addOnNewToken((token) {
print("push token: $token");
_savePushToken(token);
setState(() {
_pushToken = token;
});
});
unsubscribeOnNotificationTap = Push.instance.addOnNotificationTap((data) {
print('Notification was tapped:\n'
'Data: $data \n');
_movableInkPlugin.handlePushNotificationOpenedWithContent(data);
});
Push.instance.notificationTapWhichLaunchedAppFromTerminated.then((data) {
if (data != null) {
print(
'Notification tap launched app from terminated state:\n RemoteMessage: $data \n');
_movableInkPlugin.handlePushNotificationOpenedWithContent(data);
}
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Movable SDK Test'),
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
GestureDetector(
onTap: () {
if (_pushToken.isNotEmpty) {
Clipboard.setData(ClipboardData(text: _pushToken));
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Push token copied to clipboard!')),
);
}
},
child: Container(
width: double.infinity,
padding: const EdgeInsets.all(16),
margin: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.grey[400]!),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
const Icon(Icons.key, size: 16),
const SizedBox(width: 8),
const Text('Push Token (tap to copy)',
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 14)),
],
),
const SizedBox(height: 8),
Text(
_pushToken.isEmpty
? 'Waiting for token...'
: _pushToken,
style: TextStyle(
fontSize: 11,
fontFamily: 'monospace',
color:
_pushToken.isEmpty ? Colors.grey : Colors.black87,
),
),
],
),
),
),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(60)),
onPressed: () {
_resolveUrl();
},
child: const Text('Resolve Url'),
),
),
Text('Resolved URL: $_resolvedURL',
style: const TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.bold,
)),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(60)),
onPressed: () {
_orderCompleted();
},
child: const Text('Order Completed'),
)),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(60)),
onPressed: () {
_productViewed();
},
child: const Text('Product Viewed'),
)),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(60)),
onPressed: () {
_categoryViewed();
},
child: const Text('Category Viewed'),
)),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(60)),
onPressed: () {
_productSearched();
},
child: const Text('Product Searched'),
)),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(60)),
onPressed: () {
_productAdded();
},
child: const Text('Product Added'),
)),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(60)),
onPressed: () {
_productRemoved();
},
child: const Text('Product Removed'),
)),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: const Size.fromHeight(60)),
onPressed: () {
_surfaceMessage();
},
child: const Text('Show In App Message'),
)),
],
),
),
),
);
}
void _orderCompleted() {
final Map<String, dynamic> properties = {
"id": "123",
"revenue": "300.00",
"currency": Currency.USD.value,
"products": [
{
"id": "111-6666",
"price": "150.00",
"quantity": 2,
"meta": {"pages": 496}
}
]
};
_movableInkPlugin.orderCompleted(properties);
}
void _productSearched() {
final Map<String, dynamic> properties = {"query": "search_term"};
_movableInkPlugin.productSearched(properties);
}
void _resolveUrl() {
String urlString =
"https://www.movable-ink-7158.com/p/cpm/f9e1dde60c339938/c?mi_u=999999&url=https%3A%2F%2Fwww.movable-ink-7158.com%2Fp%2Frpm%2F4ff5ef609123c272%2Furl&url_sig=U4ZfyQRrrBylUa";
_movableInkPlugin.resolveUrl(urlString).then((value) {
setState(() {
_resolvedURL = value ?? '';
});
});
}
void _surfaceMessage() {
_movableInkPlugin.showInAppMessage(
"https://www.movable-ink-7158.com/p/rp/bc49c08945403625.html");
}
void _categoryViewed() {
final Map<String, dynamic> properties = {
"id": "sci-fi",
"title": "Sci-Fi",
"url": "https://inkrediblebooks.com/hyperion-dan-simmons",
"meta": {"pages": 496}
};
_movableInkPlugin.categoryViewed(properties);
}
void _productAdded() {
final Map<String, dynamic> properties = {
"id": "1",
"title": "Hyperion",
"price": "15.99",
"currency": Currency.USD.value,
"url": "https://inkrediblebooks.com/hyperion-dan-simmons",
"categories": [
{"id": "Sci-Fi", "url": "https://inkrediblebooks.com/categories/scifi"},
{
"id": "Fiction",
"url": "https://inkrediblebooks.com/categories/fiction"
}
],
"meta": {"pages": 496}
};
_movableInkPlugin.productAdded(properties);
}
void _productRemoved() {
final Map<String, dynamic> properties = {
"id": "1",
"title": "Hyperion",
"price": "15.99",
"currency": "USD",
"url": "https://inkrediblebooks.com/hyperion-dan-simmons",
"categories": [
{"id": "Sci-Fi", "url": "https://inkrediblebooks.com/categories/scifi"},
{
"id": "Fiction",
"url": "https://inkrediblebooks.com/categories/fiction"
}
],
"meta": {"pages": 496}
};
_movableInkPlugin.productRemoved(properties);
}
void _productViewed() {
final Map<String, dynamic> properties = {
"id": "1",
"title": "Hyperion",
"price": "15.99",
"currency": "USD",
"url": "https://inkrediblebooks.com/hyperion-dan-simmons",
"categories": [
{"id": "Sci-Fi", "url": "https://inkrediblebooks.com/categories/scifi"},
{
"id": "Fiction",
"url": "https://inkrediblebooks.com/categories/fiction"
}
],
"meta": {"pages": 496}
};
_movableInkPlugin.productViewed(properties);
}
void _logEvent() {
final Map<String, dynamic> properties = {"id": "122", "segment": "launch"};
_movableInkPlugin.logEvent("product_removed", properties);
}
}