RFlutter Alert is super customizable and easy-to-use alert / popup dialog library for Flutter. You may create reusable alert styles or add buttons as much as you want with ease.
final TextEditingController textEditingController = new TextEditingController();
final ScrollController listScrollController = new ScrollController();
final FocusNode focusNode = new FocusNode();
import 'dart:async'; import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:edupass/ChatPart/fullPhoto.dart'; import 'package:firebase_storage/firebase_storage.dart'; import 'package:flutter/material.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:image_picker/image_picker.dart'; import 'package:intl/intl.dart'; import 'package:rflutter_alert/rflutter_alert.dart'; import 'package:shared_preferences/shared_preferences.dart';
import '../main.dart'; import 'const.dart';
class Chat extends StatelessWidget { final String peerId; final String peerAvatar; final String ID;
Chat({Key key, @required this.ID ,@required this.peerId, @required this.peerAvatar}) : super(key: key);
@override Widget build(BuildContext context) { return new Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage("assets/logo.png"), fit: BoxFit.cover)), child:Scaffold( backgroundColor: Colors.transparent, appBar: AppBar( backgroundColor: Constants.labelc, title: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Material(
// new AppBar( // title: new Text( // 'CHAT', // style: TextStyle(color: primaryColor, fontWeight: FontWeight.bold), // ), // centerTitle: true, // ), body: new ChatScreen( ID: ID, peerId: peerId, peerAvatar: peerAvatar, ), ) , );
} }
class ChatScreen extends StatefulWidget { final String peerId; final String peerAvatar; final String ID;
ChatScreen({Key key,@required this.ID , @required this.peerId, @required this.peerAvatar}) : super(key: key);
@override State createState() => new ChatScreenState(id: ID, peerId: peerId, peerAvatar: peerAvatar); }
class ChatScreenState extends State {
ChatScreenState({Key key,@required this.id, @required this.peerId, @required this.peerAvatar});
String peerId; String peerAvatar; String id;
var listMessage; String groupChatId; SharedPreferences prefs;
File imageFile; bool isLoading; bool isShowSticker; String imageUrl;
final TextEditingController textEditingController = new TextEditingController(); final ScrollController listScrollController = new ScrollController(); final FocusNode focusNode = new FocusNode();
@override void initState() { super.initState(); focusNode.addListener(onFocusChange);
}
void onFocusChange() { if (focusNode.hasFocus) { // Hide sticker when keyboard appear setState(() { isShowSticker = false; }); } }
readLocal() async { prefs = await SharedPreferences.getInstance(); // id = prefs.getString('') ?? ''; // print(id+"fsdgfdgdfgdfgdfgdfgdfgdfgdfgdfgdfg"); if (id.hashCode <= peerId.hashCode) { groupChatId = '$id-$peerId'; } else { groupChatId = '$peerId-$id'; }
}
Future getImage() async { imageFile = await ImagePicker.pickImage(source: ImageSource.gallery);
}
void getSticker() { // Hide keyboard when sticker appear focusNode.unfocus(); setState(() { isShowSticker = !isShowSticker; }); }
Future uploadFile() async { String fileName = DateTime.now().millisecondsSinceEpoch.toString(); StorageReference reference = FirebaseStorage.instance.ref().child(fileName); StorageUploadTask uploadTask = reference.putFile(imageFile); StorageTaskSnapshot storageTaskSnapshot = await uploadTask.onComplete; storageTaskSnapshot.ref.getDownloadURL().then((downloadUrl) { imageUrl = downloadUrl; setState(() { isLoading = false; onSendMessage(imageUrl, 1); }); }, onError: (err) { setState(() { isLoading = false; }); Fluttertoast.showToast(msg: 'This file is not an image'); }); }
void onSendMessage(String content, int type) { // type: 0 = text, 1 = image, 2 = sticker if (content.trim() != '') { textEditingController.clear();
}
Widget buildItem(int index, DocumentSnapshot document) { if (document['idFrom'] == id) { // Right (my message) return Row( children:[
document['type'] == 0
// Text
?
// Container(
// child:
Slidable(
// padding: EdgeInsets.fromLTRB(15.0, 10.0, 15.0, 10.0), // width:MediaQuery.of(context).size.width-100, // height: 200, // decoration: BoxDecoration(color: greyColor2, borderRadius: BorderRadius.circular(8.0)), // margin: EdgeInsets.only(bottom: isLastMessageRight(index) ? 20.0 : 10.0, right: 10.0), // ) : document['type'] == 1 // Image ? Container( child: FlatButton( child: Material( child: CachedNetworkImage( placeholder: (context, url) => Container( child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation(themeColor),
),
width: 200.0,
height: 200.0,
padding: EdgeInsets.all(70.0),
decoration: BoxDecoration(
color: greyColor2,
borderRadius: BorderRadius.all(
Radius.circular(8.0),
),
),
),
errorWidget: (context, url, error) => Material(
child: Image.asset(
'images/img_not_available.jpeg',
width: 200.0,
height: 200.0,
fit: BoxFit.cover,
),
borderRadius: BorderRadius.all(
Radius.circular(8.0),
),
clipBehavior: Clip.hardEdge,
),
imageUrl: document['content'],
width: 200.0,
height: 200.0,
fit: BoxFit.cover,
),
borderRadius: BorderRadius.all(Radius.circular(8.0)),
clipBehavior: Clip.hardEdge,
),
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => FullPhoto(url: document['content'])));
},
padding: EdgeInsets.all(0),
),
margin: EdgeInsets.only(bottom: isLastMessageRight(index) ? 20.0 : 10.0, right: 10.0),
)
// Sticker
: Container(
child: new Image.asset(
'assets/${document['content']}.gif',
width: 100.0,
height: 100.0,
fit: BoxFit.cover,
),
margin: EdgeInsets.only(bottom: isLastMessageRight(index) ? 20.0 : 10.0, right: 10.0),
),
],
mainAxisAlignment: MainAxisAlignment.end,
);
} else {
// Left (peer message)
return Container(
child: Column(
children: [
Row(
children: [
isLastMessageLeft(index)
? Material(
child: CachedNetworkImage(
placeholder: (context, url) => Container(
child: CircularProgressIndicator(
strokeWidth: 1.0,
valueColor: AlwaysStoppedAnimation(themeColor),
),
width: 35.0,
height: 35.0,
padding: EdgeInsets.all(10.0),
),
imageUrl: peerAvatar,
width: 35.0,
height: 35.0,
fit: BoxFit.cover,
),
borderRadius: BorderRadius.all(
Radius.circular(18.0),
),
clipBehavior: Clip.hardEdge,
)
: Container(width: 35.0),
document['type'] == 0
? Slidable(
actionPane: SlidableDrawerActionPane(),
actions: [
IconSlideAction(
caption: 'More',
color: Colors.transparent,
foregroundColor: Colors.black,
icon: Icons.more_horiz,
// onTap: () => _showSnackBar('More'),
),
IconSlideAction(
caption: 'Delete',
color: Colors.transparent,
foregroundColor: Colors.red,
icon: (Icons.delete),
onTap: () => Alert(
context: context,
type: AlertType.error,
title: "RFLUTTER ALERT",
desc: "Flutter is more awesome with RFlutter Alert.",
buttons: [
DialogButton(
child: Text(
"COOL",
style: TextStyle(color: Colors.white, fontSize: 20),
),
onPressed: () => Navigator.pop(this.context),
width: 120,
)
],
).show(),
),
],
child: Container(
child: Text(
document['content'],
style: TextStyle(color: Colors.white),
),
padding: EdgeInsets.fromLTRB(15.0, 10.0, 15.0, 10.0),
width: 200.0,
decoration: BoxDecoration(color: primaryColor, borderRadius: BorderRadius.circular(8.0)),
margin: EdgeInsets.only(left: 10.0),
),
)
: document['type'] == 1
? Container(
child: FlatButton(
child: Material(
child: CachedNetworkImage(
placeholder: (context, url) => Container(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(themeColor),
),
width: 200.0,
height: 200.0,
padding: EdgeInsets.all(70.0),
decoration: BoxDecoration(
color: greyColor2,
borderRadius: BorderRadius.all(
Radius.circular(8.0),
),
),
),
errorWidget: (context, url, error) => Material(
child: Image.asset(
'images/img_not_available.jpeg',
width: 200.0,
height: 200.0,
fit: BoxFit.cover,
),
borderRadius: BorderRadius.all(
Radius.circular(8.0),
),
clipBehavior: Clip.hardEdge,
),
imageUrl: document['content'],
width: 200.0,
height: 200.0,
fit: BoxFit.cover,
),
borderRadius: BorderRadius.all(Radius.circular(8.0)),
clipBehavior: Clip.hardEdge,
),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => FullPhoto(url: document['content'])));
},
padding: EdgeInsets.all(0),
),
margin: EdgeInsets.only(left: 10.0),
)
: Container(
child: new Image.asset(
'assets/${document['content']}.gif',
width: 100.0,
height: 100.0,
fit: BoxFit.cover,
),
margin: EdgeInsets.only(bottom: isLastMessageRight(index) ? 20.0 : 10.0, right: 10.0),
),
],
),
}
bool isLastMessageLeft(int index) { if ((index > 0 && listMessage != null && listMessage[index - 1]['idFrom'] == id) || index == 0) { return true; } else { return false; } }
bool isLastMessageRight(int index) { if ((index > 0 && listMessage != null && listMessage[index - 1]['idFrom'] != id) || index == 0) { return true; } else { return false; } }
Future onBackPress() {
if (isShowSticker) {
setState(() {
isShowSticker = false;
});
} else {
Firestore.instance.collection('users').document(id).updateData({'chattingWith': null});
Navigator.pop(context);
}
}
@override Widget build(BuildContext context) { return WillPopScope( child: Stack( children:[
Column(
children: [
// List of messages
buildListMessage(),
}
Widget buildSticker() { return Container( child: Column( children:[
Row(
children: [
FlatButton(
onPressed: () => onSendMessage('mimi1', 2),
child: new Image.asset(
'assets/mimi1.gif',
width: 50.0,
height: 50.0,
fit: BoxFit.cover,
),
),
FlatButton(
onPressed: () => onSendMessage('mimi2', 2),
child: new Image.asset(
'assets/mimi2.gif',
width: 50.0,
height: 50.0,
fit: BoxFit.cover,
),
),
FlatButton(
onPressed: () => onSendMessage('mimi3', 2),
child: new Image.asset(
'assets/mimi3.gif',
width: 50.0,
height: 50.0,
fit: BoxFit.cover,
),
)
],
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
),
Row(
children: [
FlatButton(
onPressed: () => onSendMessage('mimi4', 2),
child: new Image.asset(
'assets/mimi4.gif',
width: 50.0,
height: 50.0,
fit: BoxFit.cover,
),
),
FlatButton(
onPressed: () => onSendMessage('mimi5', 2),
child: new Image.asset(
'assets/mimi5.gif',
width: 50.0,
height: 50.0,
fit: BoxFit.cover,
),
),
FlatButton(
onPressed: () => onSendMessage('mimi6', 2),
child: new Image.asset(
'assets/mimi6.gif',
width: 50.0,
height: 50.0,
fit: BoxFit.cover,
),
)
],
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
),
Row(
children: [
FlatButton(
onPressed: () => onSendMessage('mimi7', 2),
child: new Image.asset(
'assets/mimi7.gif',
width: 50.0,
height: 50.0,
fit: BoxFit.cover,
),
),
FlatButton(
onPressed: () => onSendMessage('mimi8', 2),
child: new Image.asset(
'assets/mimi8.gif',
width: 50.0,
height: 50.0,
fit: BoxFit.cover,
),
),
FlatButton(
onPressed: () => onSendMessage('mimi9', 2),
child: new Image.asset(
'assets/mimi9.gif',
width: 50.0,
height: 50.0,
fit: BoxFit.cover,
),
)
],
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
)
],
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
),
decoration: new BoxDecoration(
border: new Border(top: new BorderSide(color: greyColor2, width: 0.5)), color: Colors.white),
padding: EdgeInsets.all(5.0),
height: 180.0,
);
}
Widget buildLoading() { return Positioned( child: isLoading ? Container( child: Center( child: CircularProgressIndicator(valueColor: AlwaysStoppedAnimation(themeColor)),
),
color: Colors.white.withOpacity(0.8),
)
: Container(),
);
}
Widget buildInput() { return Container( child: Row( children:[
// Button send image
Material(
child: new Container(
margin: new EdgeInsets.symmetric(horizontal: 1.0),
child: new IconButton(
icon: new Icon(Icons.image),
onPressed: getImage,
color: primaryColor,
),
),
color: Colors.white,
),
Material(
child: new Container(
margin: new EdgeInsets.symmetric(horizontal: 1.0),
child: new IconButton(
icon: new Icon(Icons.face),
onPressed: getSticker,
color: primaryColor,
),
),
color: Colors.white,
),
}
Widget buildListMessage() { return Flexible( child: groupChatId == '' ? Center(child: CircularProgressIndicator(valueColor: AlwaysStoppedAnimation(themeColor)))
: StreamBuilder(
stream: Firestore.instance
.collection('messages')
.document(groupChatId)
.collection(groupChatId)
.orderBy('timestamp', descending: true)
.limit(20)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(valueColor: AlwaysStoppedAnimation(themeColor)));
} else {
listMessage = snapshot.data.documents;
return ListView.builder(
padding: EdgeInsets.all(10.0),
itemBuilder: (context, index) => buildItem(index, snapshot.data.documents[index]),
itemCount: snapshot.data.documents.length,
reverse: true,
controller: listScrollController,
);
}
},
),
);
}
}