add choose user pages

This commit is contained in:
Salvatore Giordano
2020-11-06 17:09:29 +01:00
parent 73f5b33489
commit c8bbd59732
8 changed files with 507 additions and 79 deletions
+266
View File
@@ -0,0 +1,266 @@
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_apns/flutter_apns.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart'
hide Message;
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'main.dart';
void showLocalNotification(Message message, ChannelModel channel) async {
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
final initializationSettingsAndroid =
AndroidInitializationSettings('launch_background');
final initializationSettingsIOS = IOSInitializationSettings();
final initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);
await flutterLocalNotificationsPlugin.initialize(initializationSettings);
await flutterLocalNotificationsPlugin.show(
message.id.hashCode,
'${message.user.name} @ ${channel.name}',
message.text,
NotificationDetails(
android: AndroidNotificationDetails(
'message channel',
'Message channel',
'Channel used for showing messages',
priority: Priority.high,
importance: Importance.high,
),
iOS: IOSNotificationDetails(),
),
);
}
Future backgroundHandler(Map<String, dynamic> 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',
);
}
});
}
class AdvancedOptionsPage extends StatelessWidget {
final _formKey = GlobalKey<FormState>();
final TextEditingController _apiKeyController = TextEditingController();
final TextEditingController _userIdController = TextEditingController();
final TextEditingController _userTokenController = TextEditingController();
final TextEditingController _usernameController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(
backgroundColor: StreamChatTheme.of(context).primaryColor,
elevation: 1,
centerTitle: true,
title: Text(
'Advanced Options',
style: Theme.of(context).textTheme.subtitle1.copyWith(
fontWeight: FontWeight.bold,
),
),
leading: IconButton(
icon: Icon(
StreamIcons.left,
color: Colors.black,
),
onPressed: () {
Navigator.pop(context);
},
),
),
body: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 16,
),
child: Form(
key: _formKey,
onChanged: () {},
child: Column(
children: [
TextFormField(
controller: _apiKeyController,
validator: (value) {
if (value.isEmpty) {
return 'Please enter the user Chat API Key';
}
return null;
},
decoration: InputDecoration(
labelStyle: TextStyle(
fontSize: 14,
color: Colors.black.withOpacity(.5),
),
border: UnderlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide.none,
),
fillColor: Color(0xffF5F5F5),
filled: true,
labelText: 'Chat API Key',
),
textInputAction: TextInputAction.next,
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: TextFormField(
controller: _userIdController,
validator: (value) {
if (value.isEmpty) {
return 'Please enter the User ID';
}
return null;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
labelStyle: TextStyle(
fontSize: 14,
color: Colors.black.withOpacity(.5),
),
border: UnderlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide.none,
),
fillColor: Color(0xffF5F5F5),
filled: true,
labelText: 'User ID',
),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: TextFormField(
controller: _userTokenController,
validator: (value) {
if (value.isEmpty) {
return 'Please enter the user token';
}
return null;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
labelStyle: TextStyle(
fontSize: 14,
color: Colors.black.withOpacity(.5),
),
border: UnderlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide.none,
),
fillColor: Color(0xffF5F5F5),
filled: true,
labelText: 'User Token',
),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: TextFormField(
controller: _usernameController,
textInputAction: TextInputAction.done,
decoration: InputDecoration(
labelStyle: TextStyle(
fontSize: 14,
color: Colors.black.withOpacity(.5),
),
border: UnderlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide.none,
),
fillColor: Color(0xffF5F5F5),
filled: true,
labelText: 'Username (optional)',
),
),
),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: FlatButton(
color: StreamChatTheme.of(context).accentColor,
minWidth: double.infinity,
height: 48,
child: Text(
'Login',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(26),
),
onPressed: () async {
if (_formKey.currentState.validate()) {
final apiKey = _apiKeyController.text;
final userId = _userIdController.text;
final userToken = _userTokenController.text;
final username = _usernameController.text;
final client = StreamChat.of(context).client;
client.apiKey = apiKey;
await client.setUser(
User(id: userId, extraData: {
'name': username,
}),
userToken,
);
if (!kIsWeb) {
_initNotifications(client);
}
Navigator.pop(context);
await Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) {
return StreamChat(
client: client,
child: ChannelListPage(),
);
},
),
);
}
},
),
),
)
],
),
),
),
);
}
}
+227
View File
@@ -0,0 +1,227 @@
import 'dart:io';
import 'package:example/advanced_options_page.dart';
import 'package:example/main.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_apns/flutter_apns.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart'
hide Message;
import 'package:flutter_svg/flutter_svg.dart';
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(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);
await flutterLocalNotificationsPlugin.initialize(initializationSettings);
await flutterLocalNotificationsPlugin.show(
message.id.hashCode,
'${message.user.name} @ ${channel.name}',
message.text,
NotificationDetails(
android: AndroidNotificationDetails(
'message channel',
'Message channel',
'Channel used for showing messages',
priority: Priority.high,
importance: Importance.high,
),
iOS: IOSNotificationDetails(),
),
);
}
Future backgroundHandler(Map<String, dynamic> 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',
);
}
});
}
class ChooseUserPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final users = <String, User>{
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoidmlzaGFsIn0._JHWzo92fpTWZMZriJHXqOng6ShYVmWrdaIaPwEPKBg':
User(
id: 'vishal',
extraData: {
'name': 'Vishal',
},
),
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoic3VwZXItYmFuZC05In0.0L6lGoeLwkz0aZRUcpZKsvaXtNEDHBcezVTZ0oPq40A':
User(
id: 'super-band-9',
extraData: {
'name': 'John Doe',
},
),
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoic2FsdmF0b3JlIn0.GMEKyEhONmFnqtkf1TR1A3oUOSIWhjfQv5RpI906dAM':
User(
id: 'salvatore',
extraData: {
'name': 'Salvatore',
},
),
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoidG9tbWFzbyJ9.GTalMeZHaBdpIM5w-KWrVIDSy-ODkHTRkf1GZbWAveM':
User(
id: 'tommaso',
extraData: {
'name': 'Tommaso',
},
),
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiamFhcCJ9.xpGE2lu4OoYS7-2yy6PbF0gJnxOaxeGO4EU6xo4EdMU':
User(
id: 'jaap',
extraData: {
'name': 'Jaap',
},
),
};
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(
top: 34,
bottom: 20,
),
child: Center(
child: SvgPicture.asset(
'assets/logo.svg',
height: 40,
),
),
),
Padding(
padding: const EdgeInsets.only(bottom: 13.0),
child: Text(
'Welcome to Stream Chat',
style: TextStyle(
fontSize: 22,
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
),
Text(
'Select a user to try the Flutter SDK:',
style: TextStyle(
fontSize: 14.5,
color: Colors.black,
),
),
Expanded(
child: ListView(
children: [
...users.entries.map((entry) {
final token = entry.key;
final user = entry.value;
return ListTile(
onTap: () async {
final client = StreamChat.of(context).client;
await client.setUser(
User(id: user.id, extraData: {
'name': user.name,
}),
token,
);
if (!kIsWeb) {
_initNotifications(client);
}
await Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) {
return StreamChat(
client: client,
child: ChannelListPage(),
);
},
),
);
},
leading: UserAvatar(
user: user,
constraints: BoxConstraints.tight(
Size.fromRadius(20),
),
),
title: Text(
user.name,
style: TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text('Stream test account'),
trailing: Icon(
StreamIcons.arrow_right,
color: StreamChatTheme.of(context).accentColor,
),
);
}),
ListTile(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AdvancedOptionsPage(),
),
);
},
leading: CircleAvatar(
child: Icon(
StreamIcons.settings,
color: Colors.black,
),
backgroundColor: StreamChatTheme.of(context).secondaryColor,
),
title: Text(
'Advanced Options',
style: TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text('Custom settings'),
trailing: Icon(
StreamIcons.arrow_right,
color: StreamChatTheme.of(context).accentColor,
),
),
],
),
),
],
),
);
}
}
+3 -74
View File
@@ -1,70 +1,11 @@
import 'dart:io';
import 'package:example/choose_user_page.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
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(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);
await flutterLocalNotificationsPlugin.initialize(initializationSettings);
await flutterLocalNotificationsPlugin.show(
message.id.hashCode,
'${message.user.name} @ ${channel.name}',
message.text,
NotificationDetails(
android: AndroidNotificationDetails(
'message channel',
'Message channel',
'Channel used for showing messages',
priority: Priority.high,
importance: Importance.high,
),
iOS: IOSNotificationDetails(),
),
);
}
Future backgroundHandler(Map<String, dynamic> 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',
@@ -74,17 +15,6 @@ void main() async {
persistenceEnabled: true,
);
await client.setUser(
User(id: 'super-band-9', extraData: {
'name': 'Jonathan Doe',
}),
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoic3VwZXItYmFuZC05In0.0L6lGoeLwkz0aZRUcpZKsvaXtNEDHBcezVTZ0oPq40A',
);
if (!kIsWeb) {
_initNotifications(client);
}
runApp(MyApp(client));
}
@@ -98,16 +28,15 @@ class MyApp extends StatelessWidget {
return MaterialApp(
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
//TODO change to system once dark theme is implemented
themeMode: ThemeMode.light,
///TODO change to system once dark theme is implemented
builder: (context, widget) {
return StreamChat(
child: widget,
client: client,
);
},
home: ChannelListPage(),
home: ChooseUserPage(),
);
}
}