import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_apns/apns.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart' hide Message; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; void showLocalNotification(Message message, ChannelModel channel) async { FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); final initializationSettingsAndroid = AndroidInitializationSettings('launch_background'); final initializationSettingsIOS = IOSInitializationSettings(); final initializationSettings = InitializationSettings( initializationSettingsAndroid, initializationSettingsIOS, ); await flutterLocalNotificationsPlugin.initialize(initializationSettings); await flutterLocalNotificationsPlugin.show( message.id.hashCode, '${message.user.name} @ ${channel.name}', message.text, NotificationDetails( AndroidNotificationDetails( 'message channel', 'Message channel', 'Channel used for showing messages', priority: Priority.High, importance: Importance.High, ), IOSNotificationDetails(), ), ); } Future backgroundHandler(Map notification) async { final messageId = notification['data']['message_id']; final notificationData = await NotificationService.getAndStoreMessage(messageId); showLocalNotification( notificationData.message, notificationData.channel, ); } void _initNotifications(Client client) { final connector = createPushConnector(); connector.configure( onBackgroundMessage: backgroundHandler, ); connector.requestNotificationPermissions(); connector.token.addListener(() { if (connector.token.value != null) { client.addDevice( connector.token.value, Platform.isAndroid ? 'firebase' : 'apn', ); } }); } void main() async { final client = Client( 's2dxdhpxd94g', logLevel: Level.INFO, showLocalNotification: Platform.isAndroid ? showLocalNotification : null, ); await client.setUser( User(id: 'super-band-9'), 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoic3VwZXItYmFuZC05In0.0L6lGoeLwkz0aZRUcpZKsvaXtNEDHBcezVTZ0oPq40A', ); _initNotifications(client); runApp(MyApp(client)); } class MyApp extends StatelessWidget { final Client client; MyApp(this.client); @override Widget build(BuildContext context) { final theme = ThemeData(); return MaterialApp( theme: theme, themeMode: ThemeMode.system, home: Container( child: StreamChat( streamChatThemeData: StreamChatThemeData.fromTheme(theme), client: client, child: ChannelListPage(), ), ), ); } } class ChannelListPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: ChannelsBloc( child: ChannelListView( filter: { 'members': { '\$in': [StreamChat.of(context).user.id], } }, sort: [SortOption('last_message_at')], pagination: PaginationParams( limit: 20, ), channelWidget: ChannelPage(), ), ), ); } } class ChannelPage extends StatelessWidget { const ChannelPage({ Key key, }) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: ChannelHeader(), body: Column( children: [ Expanded( child: Stack( children: [ MessageListView( showOtherMessageUsername: true, showVideoFullScreen: false, threadBuilder: (_, parentMessage) { return ThreadPage( parent: parentMessage, ); }, ), Positioned.fill( child: Padding( padding: const EdgeInsets.symmetric( horizontal: 8.0, vertical: 4, ), child: TypingIndicator( alignment: Alignment.bottomRight, ), ), ), ], ), ), MessageInput(), ], ), ); } } class ThreadPage extends StatelessWidget { final Message parent; ThreadPage({ Key key, this.parent, }) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: ThreadHeader( parent: parent, ), body: Column( children: [ Expanded( child: MessageListView( parentMessage: parent, ), ), if (parent.type != 'deleted') MessageInput( parentMessage: parent, ), ], ), ); } }