Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions intercom_flutter/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## 9.6.2

* Removed deprecated `handlePushMessage` API (removed from native Intercom SDK)
* Added `getWindowDidHideStream` to listen for when the Intercom window is hidden (iOS only).

## 9.6.1

Expand Down
1 change: 1 addition & 0 deletions intercom_flutter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ But you can pre-define some Intercom settings, if you want (optional).
- [ ] handlePush
- [ ] displayCarousel
- [ ] displayHelpCenterCollections
- [ ] getWindowDidHideStream

## Using Intercom keys with `--dart-define`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ import io.intercom.android.sdk.identity.Registration
import io.intercom.android.sdk.push.IntercomPushClient
import io.intercom.android.sdk.ui.theme.ThemeMode

// No-op stream handler for windowDidHide event since it's only supported on iOS.
class WindowDidHideStreamHandler : EventChannel.StreamHandler {
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {}
override fun onCancel(arguments: Any?) {}
}

class IntercomFlutterPlugin : FlutterPlugin, MethodCallHandler, EventChannel.StreamHandler, ActivityAware {
companion object {
@JvmStatic
Expand All @@ -33,6 +39,8 @@ class IntercomFlutterPlugin : FlutterPlugin, MethodCallHandler, EventChannel.Str
channel.setMethodCallHandler(IntercomFlutterPlugin())
val unreadEventChannel = EventChannel(flutterPluginBinding.binaryMessenger, "maido.io/intercom/unread")
unreadEventChannel.setStreamHandler(IntercomFlutterPlugin())
val windowDidHideEventChannel = EventChannel(flutterPluginBinding.binaryMessenger, "maido.io/intercom/windowDidHide")
windowDidHideEventChannel.setStreamHandler(WindowDidHideStreamHandler())
application = flutterPluginBinding.applicationContext as Application
}

Expand Down
76 changes: 63 additions & 13 deletions intercom_flutter/example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:intercom_flutter/intercom_flutter.dart';

Expand All @@ -13,7 +16,41 @@ void main() async {
runApp(SampleApp());
}

class SampleApp extends StatelessWidget {
class SampleApp extends StatefulWidget {
@override
_SampleAppState createState() => _SampleAppState();
}

class _SampleAppState extends State<SampleApp> {
StreamSubscription? _windowDidHideSubscription;

@override
void initState() {
super.initState();
// Listen for when the Intercom window is hidden
if (!kIsWeb) {
_windowDidHideSubscription =
Intercom.instance.getWindowDidHideStream().listen((_) {
// This will be called when the Intercom window is closed
// Only works on iOS
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Intercom window was closed!'),
duration: Duration(seconds: 2),
),
);
}
});
}
}

@override
void dispose() {
_windowDidHideSubscription?.cancel();
super.dispose();
}

@override
Widget build(BuildContext context) {
return MaterialApp(
Expand All @@ -22,18 +59,31 @@ class SampleApp extends StatelessWidget {
title: const Text('Intercom example app'),
),
body: Center(
child: TextButton(
onPressed: () {
// NOTE:
// Messenger will load the messages only if the user is registered
// in Intercom.
// Either identified or unidentified.
// So make sure to login the user in Intercom first before opening
// the intercom messenger.
// Otherwise messenger will not load.
Intercom.instance.displayMessenger();
},
child: Text('Show messenger'),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () {
// NOTE:
// Messenger will load the messages only if the user is registered
// in Intercom.
// Either identified or unidentified.
// So make sure to login the user in Intercom first before opening
// the intercom messenger.
// Otherwise messenger will not load.
Intercom.instance.displayMessenger();
},
child: Text('Show messenger'),
),
if (!kIsWeb) ...[
SizedBox(height: 20),
Text(
'Close the Intercom window to see the notification!',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16),
),
],
],
),
),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#import <Intercom/Intercom.h>

id unread;
id windowDidHide;

@implementation UnreadStreamHandler
- (FlutterError*)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)eventSink {
Expand All @@ -18,6 +19,20 @@ - (FlutterError*)onCancelWithArguments:(id)arguments {
}
@end

@implementation WindowDidHideStreamHandler
- (FlutterError*)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)eventSink {
windowDidHide = [[NSNotificationCenter defaultCenter] addObserverForName:IntercomWindowDidHideNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
eventSink(@(YES));
}];
return nil;
}

- (FlutterError*)onCancelWithArguments:(id)arguments {
[[NSNotificationCenter defaultCenter] removeObserver:windowDidHide];
return nil;
}
@end

@implementation IntercomFlutterPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
IntercomFlutterPlugin* instance = [[IntercomFlutterPlugin alloc] init];
Expand All @@ -31,6 +46,12 @@ + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
[[UnreadStreamHandler alloc] init];
[unreadChannel setStreamHandler:unreadStreamHandler];

FlutterEventChannel* windowDidHideChannel = [FlutterEventChannel eventChannelWithName:@"maido.io/intercom/windowDidHide"
binaryMessenger:[registrar messenger]];
WindowDidHideStreamHandler* windowDidHideStreamHandler =
[[WindowDidHideStreamHandler alloc] init];
[windowDidHideChannel setStreamHandler:windowDidHideStreamHandler];

}

- (void) handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@

@interface UnreadStreamHandler : NSObject <FlutterStreamHandler>
@end

@interface WindowDidHideStreamHandler : NSObject <FlutterStreamHandler>
@end
9 changes: 9 additions & 0 deletions intercom_flutter/lib/intercom_flutter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@ class Intercom {
return IntercomFlutterPlatform.instance.getUnreadStream();
}

/// You can listen for when the Intercom window is hidden.
///
/// This stream emits when the Intercom window (messenger, help center, etc.) is closed.
/// This allows developers to perform certain actions in their app when the Intercom window is closed.
/// Only available on iOS.
Stream<dynamic> getWindowDidHideStream() {
return IntercomFlutterPlatform.instance.getWindowDidHideStream();
}

/// This method allows you to set a fixed bottom padding for in app messages and the launcher.
///
/// It is useful if your app has a tab bar or similar UI at the bottom of your window.
Expand Down
4 changes: 2 additions & 2 deletions intercom_flutter/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ dependencies:
sdk: flutter
flutter_web_plugins:
sdk: flutter
intercom_flutter_platform_interface: ^2.0.6
intercom_flutter_web: ^1.1.11
intercom_flutter_platform_interface: ^2.0.7
intercom_flutter_web: ^1.1.12

dev_dependencies:
flutter_test:
Expand Down
28 changes: 28 additions & 0 deletions intercom_flutter/test/intercom_flutter_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,34 @@ void main() {
});
});

group('WindowDidHide', () {
const String channelName = 'maido.io/intercom/windowDidHide';
const MethodChannel channel = MethodChannel(channelName);
final bool value = true;

setUp(() {
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(channel, (MethodCall methodCall) async {
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.handlePlatformMessage(
channelName,
const StandardMethodCodec().encodeSuccessEnvelope(value),
(ByteData? data) {},
);
return;
});
});

tearDown(() {
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(channel, null);
});

test('testStream', () async {
expect(await Intercom.instance.getWindowDidHideStream().first, value);
});
});

test('displayArticle', () async {
final String testArticleId = "123456";
await Intercom.instance.displayArticle(testArticleId);
Expand Down
5 changes: 5 additions & 0 deletions intercom_flutter_platform_interface/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 2.0.7

* Added method `getWindowDidHideStream`.
* Removed deprecated `handlePushMessage`.

## 2.0.6

* Added method `setThemeMode`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ abstract class IntercomFlutterPlatform extends PlatformInterface {
throw UnimplementedError('getUnreadStream() has not been implemented.');
}

/// You can listen for when the Intercom window is hidden.
///
/// This stream emits when the Intercom window (messenger, help center, etc.) is closed.
/// This allows developers to perform certain actions in their app when the Intercom window is closed.
/// Only available on iOS.
Stream<dynamic> getWindowDidHideStream() {
throw UnimplementedError(
'getWindowDidHideStream() has not been implemented.');
}

/// To make sure that conversations between you and your users are kept private
/// and that one user can't impersonate another then you need you need to setup
/// the identity verification.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import 'package:intercom_flutter_platform_interface/intercom_status_callback.dar

const MethodChannel _channel = MethodChannel('maido.io/intercom');
const EventChannel _unreadChannel = EventChannel('maido.io/intercom/unread');
const EventChannel _windowDidHideChannel =
EventChannel('maido.io/intercom/windowDidHide');

/// An implementation of [IntercomFlutterPlatform] that uses method channels.
class MethodChannelIntercomFlutter extends IntercomFlutterPlatform {
Expand All @@ -26,6 +28,11 @@ class MethodChannelIntercomFlutter extends IntercomFlutterPlatform {
return _unreadChannel.receiveBroadcastStream();
}

@override
Stream<dynamic> getWindowDidHideStream() {
return _windowDidHideChannel.receiveBroadcastStream();
}

@override
Future<void> setUserHash(String userHash) async {
await _channel.invokeMethod('setUserHash', {'userHash': userHash});
Expand Down
2 changes: 1 addition & 1 deletion intercom_flutter_platform_interface/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: intercom_flutter_platform_interface
description: A common platform interface for the intercom_flutter plugin.
version: 2.0.6
version: 2.0.7
homepage: https://github.com/v3rm0n/intercom_flutter

dependencies:
Expand Down
5 changes: 5 additions & 0 deletions intercom_flutter_web/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 1.1.12

* Updated `intercom_flutter_platform_interface` to `^2.0.7`.
* Removed deprecated `handlePushMessage`.

## 1.1.11

* JSON-encode `intercomSettings` before injecting the Intercom script to avoid invalid JavaScript
Expand Down
4 changes: 2 additions & 2 deletions intercom_flutter_web/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: intercom_flutter_web
description: Web platform implementation of intercom_flutter
version: 1.1.11
version: 1.1.12
homepage: https://github.com/v3rm0n/intercom_flutter

flutter:
Expand All @@ -15,7 +15,7 @@ dependencies:
sdk: flutter
flutter_web_plugins:
sdk: flutter
intercom_flutter_platform_interface: ^2.0.6
intercom_flutter_platform_interface: ^2.0.7
uuid: ^4.2.1 # to get the random uuid for loginUnidentifiedUser in web
web: ^1.0.0

Expand Down
Loading