723 lines
31 KiB
Dart
723 lines
31 KiB
Dart
import 'dart:async';
|
||
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||
import 'package:get/get.dart';
|
||
import 'package:glassmorphism/glassmorphism.dart';
|
||
import 'package:regroup/Common/CommonGlassmorphism.dart';
|
||
import 'package:regroup/Common/CommonWidget.dart';
|
||
import 'package:regroup/Utils/Common/ImageUpload.dart';
|
||
import 'package:regroup/Utils/Common/sized_box.dart';
|
||
import 'package:remove_emoji_input_formatter/remove_emoji_input_formatter.dart';
|
||
|
||
class GroupChatPage extends StatefulWidget {
|
||
const GroupChatPage({super.key});
|
||
|
||
@override
|
||
State<GroupChatPage> createState() => _GroupChatPageState();
|
||
}
|
||
|
||
class _GroupChatPageState extends State<GroupChatPage> {
|
||
ScrollController myController = ScrollController();
|
||
|
||
List<ChatMessage> messages = [
|
||
ChatMessage(
|
||
messageContent: "That sounds great! I’m in. What time works for you?",
|
||
messageType: "receiver",
|
||
isread: true,
|
||
image: 'assets/images/png/Photo.png'),
|
||
ChatMessage(
|
||
messageContent:
|
||
"Lorem ipsum is simply dummy text of the printing and typesetting industry.",
|
||
messageType: "sender",
|
||
isread: true,
|
||
image: 'assets/images/png/groupchat2.png'),
|
||
ChatMessage(
|
||
messageContent:
|
||
"Lorem ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
|
||
messageType: "receiver",
|
||
isread: true,
|
||
image: 'assets/images/png/groupchat3.png'),
|
||
ChatMessage(
|
||
messageContent: "That sounds great! I’m in. What time works for you?",
|
||
messageType: "receiver",
|
||
isread: true,
|
||
image: 'assets/images/png/groupchat4.png'),
|
||
];
|
||
|
||
String? attachimage;
|
||
|
||
final messageController = TextEditingController();
|
||
|
||
bool isImageAdded = false;
|
||
|
||
void _showContextMenu(BuildContext context, Offset offset) {
|
||
showMenu(
|
||
color: const Color(0XFf222935),
|
||
context: context,
|
||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.r)),
|
||
position:
|
||
RelativeRect.fromLTRB(offset.dx, offset.dy, offset.dx, offset.dy),
|
||
items: [
|
||
PopupMenuItem<int>(
|
||
value: 0,
|
||
child: Column(children: [
|
||
sizedBoxHeight(10.h),
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
children: [
|
||
const Text("Mute chat", style: TextStyle(color: Colors.white)),
|
||
Image.asset(
|
||
'assets/images/png/mute.png',
|
||
width: 19.w,
|
||
height: 19.h,
|
||
)
|
||
],
|
||
),
|
||
Divider(
|
||
thickness: 0.6.h,
|
||
color: const Color(0xffFFFFFF).withOpacity(0.72),
|
||
)
|
||
]),
|
||
),
|
||
PopupMenuItem<int>(
|
||
value: 1,
|
||
child: Column(
|
||
children: [
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
children: [
|
||
const Text("Pin chat", style: TextStyle(color: Colors.white)),
|
||
Image.asset(
|
||
'assets/images/png/pin.png',
|
||
width: 19.w,
|
||
height: 19.h,
|
||
)
|
||
],
|
||
),
|
||
Divider(
|
||
thickness: 0.6.h,
|
||
color: const Color(0xffFFFFFF).withOpacity(0.72),
|
||
)
|
||
],
|
||
),
|
||
),
|
||
PopupMenuItem<int>(
|
||
value: 1,
|
||
child: Column(
|
||
children: [
|
||
const Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
children: [
|
||
Text("Search", style: TextStyle(color: Colors.white)),
|
||
Icon(
|
||
Icons.search,
|
||
size: 35,
|
||
color: Colors.white,
|
||
),
|
||
],
|
||
),
|
||
Divider(
|
||
thickness: 0.6.h,
|
||
color: const Color(0xffFFFFFF).withOpacity(0.72),
|
||
)
|
||
],
|
||
),
|
||
),
|
||
PopupMenuItem<int>(
|
||
value: 1,
|
||
child: Column(
|
||
children: [
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
children: [
|
||
const Text("Profile", style: TextStyle(color: Colors.white)),
|
||
Image.asset(
|
||
'assets/images/png/profile.png',
|
||
width: 19.w,
|
||
height: 19.h,
|
||
)
|
||
],
|
||
),
|
||
Divider(
|
||
thickness: 0.6.h,
|
||
color: const Color(0xffFFFFFF).withOpacity(0.72),
|
||
)
|
||
],
|
||
),
|
||
),
|
||
PopupMenuItem<int>(
|
||
value: 1,
|
||
child: Column(
|
||
children: [
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
children: [
|
||
const Text("Block chat", style: TextStyle(color: Colors.white)),
|
||
Image.asset(
|
||
'assets/images/png/blockchat.png',
|
||
width: 19.w,
|
||
height: 19.h,
|
||
)
|
||
],
|
||
),
|
||
Divider(
|
||
thickness: 0.6.h,
|
||
color: const Color(0xffFFFFFF).withOpacity(0.72),
|
||
)
|
||
],
|
||
),
|
||
),
|
||
PopupMenuItem<int>(
|
||
value: 2,
|
||
child: Padding(
|
||
padding: EdgeInsets.only(bottom: 10.h),
|
||
child: Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
children: [
|
||
const Text("Delete chat", style: TextStyle(color: Colors.red)),
|
||
// Icon(Icons.delete, color: Colors.red),
|
||
Image.asset(
|
||
'assets/images/png/deletetred.png',
|
||
width: 19.w,
|
||
height: 19.h,
|
||
)
|
||
],
|
||
),
|
||
),
|
||
),
|
||
],
|
||
).then((value) {
|
||
if (value != null) {
|
||
_onMenuItemSelected(value);
|
||
}
|
||
});
|
||
}
|
||
|
||
void _onMenuItemSelected(int value) {
|
||
switch (value) {
|
||
case 0:
|
||
// Mute chat
|
||
print('Mute chat selected');
|
||
break;
|
||
case 1:
|
||
// Pin chat
|
||
print('Pin chat selected');
|
||
break;
|
||
case 2:
|
||
// Delete chat
|
||
print('Search chat selected');
|
||
break;
|
||
case 3:
|
||
// Pin chat
|
||
print('Profile chat selected');
|
||
break;
|
||
case 4:
|
||
// Pin chat
|
||
print('block chat selected');
|
||
break;
|
||
case 5:
|
||
// Pin chat
|
||
print('delete chat selected');
|
||
break;
|
||
}
|
||
}
|
||
|
||
void _sendMessage() {
|
||
if (messageController.text.isNotEmpty) {
|
||
setState(() {
|
||
messages.add(ChatMessage(
|
||
messageContent: messageController.text,
|
||
messageType: "sender",
|
||
isread: false,
|
||
image: 'assets/images/png/groupchat2.png'));
|
||
messageController.clear();
|
||
});
|
||
}
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
Timer(const Duration(milliseconds: 50),
|
||
() => myController.jumpTo(myController.position.maxScrollExtent));
|
||
return GestureDetector(
|
||
onTap: () {
|
||
Get.focusScope?.unfocus();
|
||
},
|
||
child: Scaffold(
|
||
backgroundColor: const Color.fromARGB(255, 18, 32, 47),
|
||
appBar: AppBar(
|
||
elevation: 0,
|
||
automaticallyImplyLeading: false,
|
||
backgroundColor: const Color(0xFF222935).withOpacity(0.50),
|
||
flexibleSpace: SafeArea(
|
||
child: Container(
|
||
// height: 90.h,
|
||
padding: EdgeInsets.only(right: 10.w, left: 4.w),
|
||
child: Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
children: <Widget>[
|
||
InkWell(
|
||
onTap: () {
|
||
Get.back();
|
||
},
|
||
child: Row(
|
||
children: [
|
||
sizedBoxWidth(10.w),
|
||
commonGlassContainer(
|
||
border: 0.9,
|
||
width: 40.w,
|
||
height: 40.h,
|
||
opacity1: 0.24,
|
||
opacity2: 0.24,
|
||
borderradius: 100,
|
||
customWidget: Center(
|
||
child: Image.asset(
|
||
'assets/images/png/appbararrowbutton.png')
|
||
// Icon(
|
||
// Icons.arrow_back,
|
||
// color: Colors.white,
|
||
// size: 20.sp,
|
||
// ),
|
||
),
|
||
),
|
||
],
|
||
)),
|
||
SizedBox(
|
||
width: 18.w,
|
||
),
|
||
Container(
|
||
width: 40.h,
|
||
height: 40.h,
|
||
decoration: BoxDecoration(
|
||
borderRadius: BorderRadius.circular(25.h),
|
||
image: const DecorationImage(
|
||
image:
|
||
AssetImage("assets/images/png/groupchat.png"),
|
||
fit: BoxFit.cover)),
|
||
),
|
||
SizedBox(
|
||
width: 12.w,
|
||
),
|
||
Expanded(
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
children: <Widget>[
|
||
Row(
|
||
children: [
|
||
Text(
|
||
'Liverpool FC',
|
||
style: TextStyle(
|
||
fontSize: 16.sp,
|
||
fontWeight: FontWeight.w400,
|
||
color: Colors.white),
|
||
),
|
||
sizedBoxWidth(4.w),
|
||
Image.asset(
|
||
'assets/images/png/noto_soccer-ball.png')
|
||
],
|
||
),
|
||
SizedBox(
|
||
height: 2.h,
|
||
),
|
||
Text(
|
||
"Ryan, Jaxson, Dulce, Nolan ",
|
||
style: TextStyle(
|
||
color: const Color(0xffFCFCFC).withOpacity(0.80),
|
||
fontSize: 12.sp,
|
||
fontWeight: FontWeight.w400),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
InkWell(
|
||
onTapDown: (details) {
|
||
_showContextMenu(context, details.globalPosition);
|
||
},
|
||
child: Container(
|
||
width: 30,
|
||
height: 20,
|
||
child: Image.asset(
|
||
'assets/images/png/vertical3dots.png')))
|
||
|
||
// ignore: prefer_const_constructors
|
||
],
|
||
),
|
||
),
|
||
),
|
||
),
|
||
body: Stack(
|
||
children: [
|
||
Container(
|
||
decoration: const BoxDecoration(
|
||
image: DecorationImage(
|
||
image: AssetImage("assets/images/png/Ellipse 1496.png"),
|
||
fit: BoxFit.fill)),
|
||
),
|
||
GlassmorphicContainer(
|
||
width: MediaQuery.of(context).size.width,
|
||
height:
|
||
// 500.h,
|
||
MediaQuery.of(context).size.height,
|
||
borderRadius: 2,
|
||
blur: 6,
|
||
alignment: Alignment.bottomLeft,
|
||
border: 2,
|
||
linearGradient: LinearGradient(
|
||
begin: Alignment.topCenter,
|
||
end: Alignment.bottomCenter,
|
||
colors: [
|
||
const Color(0XFF222935).withOpacity(0.60),
|
||
const Color(0XFF222935).withOpacity(0.60),
|
||
const Color(0XFF222935).withOpacity(0.60),
|
||
const Color(0XFF222935).withOpacity(0.60),
|
||
],
|
||
),
|
||
borderGradient: LinearGradient(
|
||
begin: Alignment.topCenter,
|
||
end: Alignment.bottomCenter,
|
||
colors: [
|
||
const Color(0XFF222935).withOpacity(0.60),
|
||
const Color(0XFF222935).withOpacity(0.60),
|
||
],
|
||
),
|
||
child: Stack(
|
||
children: [
|
||
ListView.builder(
|
||
controller: myController,
|
||
itemCount: messages.length,
|
||
padding: const EdgeInsets.only(top: 10.0, bottom: 70.0),
|
||
physics: const BouncingScrollPhysics(),
|
||
itemBuilder: (context, index) {
|
||
return messages[index].messageType == "receiver"
|
||
? Padding(
|
||
padding: const EdgeInsets.only(
|
||
left: 16.0,
|
||
top: 5.0,
|
||
bottom: 5.0,
|
||
right: 90.0),
|
||
child: Align(
|
||
alignment: Alignment.topLeft,
|
||
child: Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
crossAxisAlignment: CrossAxisAlignment.end,
|
||
mainAxisAlignment: MainAxisAlignment.end,
|
||
children: [
|
||
Container(
|
||
width: 30,
|
||
height: 30,
|
||
decoration: ShapeDecoration(
|
||
image: DecorationImage(
|
||
image: AssetImage(
|
||
messages[index].image,
|
||
),
|
||
fit: BoxFit.fill,
|
||
),
|
||
shape: const OvalBorder(),
|
||
),
|
||
),
|
||
sizedBoxWidth(2.w),
|
||
Flexible(
|
||
child: Container(
|
||
decoration: ShapeDecoration(
|
||
gradient: LinearGradient(
|
||
begin: const Alignment(1.00, -0.03),
|
||
end: const Alignment(-1, 0.03),
|
||
colors: [
|
||
Colors.white.withOpacity(
|
||
0.05999999865889549),
|
||
Colors.white.withOpacity(
|
||
0.07999999821186066)
|
||
],
|
||
),
|
||
shape: const RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.only(
|
||
topLeft: Radius.circular(20),
|
||
topRight: Radius.circular(20),
|
||
bottomRight:
|
||
Radius.circular(20),
|
||
),
|
||
),
|
||
),
|
||
padding: const EdgeInsets.all(10.0),
|
||
child: Column(
|
||
crossAxisAlignment:
|
||
CrossAxisAlignment.start,
|
||
children: [
|
||
Text(
|
||
messages[index].messageContent,
|
||
style: TextStyle(
|
||
fontSize: 16.sp,
|
||
color: Colors.white,
|
||
fontWeight: FontWeight.w400,
|
||
fontFamily: 'Helvetica',
|
||
),
|
||
),
|
||
sizedBoxHeight(2.h),
|
||
messages[index].isread == true
|
||
? Image.asset(
|
||
'assets/images/png/messagereadcheckmark.png')
|
||
: Image.asset(
|
||
'assets/images/png/messagedelivered.png'),
|
||
],
|
||
),
|
||
),
|
||
)
|
||
],
|
||
),
|
||
),
|
||
)
|
||
: Padding(
|
||
padding: const EdgeInsets.only(
|
||
right: 16.0,
|
||
top: 5.0,
|
||
bottom: 5.0,
|
||
left: 90.0),
|
||
child: Align(
|
||
alignment: Alignment.topRight,
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.end,
|
||
children: [
|
||
Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
crossAxisAlignment:
|
||
CrossAxisAlignment.end,
|
||
mainAxisAlignment:
|
||
MainAxisAlignment.end,
|
||
children: [
|
||
Flexible(
|
||
child: Container(
|
||
decoration: const ShapeDecoration(
|
||
gradient: LinearGradient(
|
||
begin: Alignment(1.00, 0.05),
|
||
end: Alignment(-1, -0.05),
|
||
colors: [
|
||
Color(0xFFD90B2E),
|
||
Color(0x38D90B2E)
|
||
],
|
||
),
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius:
|
||
BorderRadius.only(
|
||
topLeft: Radius.circular(20),
|
||
topRight: Radius.circular(20),
|
||
bottomLeft:
|
||
Radius.circular(20),
|
||
)),
|
||
),
|
||
padding:
|
||
const EdgeInsets.all(10.0),
|
||
child: Column(
|
||
crossAxisAlignment:
|
||
CrossAxisAlignment.end,
|
||
children: [
|
||
Text(
|
||
messages[index]
|
||
.messageContent,
|
||
style: TextStyle(
|
||
fontSize: 16.sp,
|
||
color: Colors.white,
|
||
fontFamily: 'Helvetica',
|
||
fontWeight:
|
||
FontWeight.w400,
|
||
),
|
||
),
|
||
sizedBoxHeight(2.h),
|
||
messages[index].isread == true
|
||
? Image.asset(
|
||
'assets/images/png/messagereadcheckmark.png')
|
||
: Image.asset(
|
||
'assets/images/png/messagedelivered.png'),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
sizedBoxWidth(2.w),
|
||
Container(
|
||
width: 30,
|
||
height: 30,
|
||
decoration: ShapeDecoration(
|
||
image: DecorationImage(
|
||
image: AssetImage(
|
||
messages[index].image,
|
||
),
|
||
fit: BoxFit.fill,
|
||
),
|
||
shape: const OvalBorder(),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
},
|
||
),
|
||
Align(
|
||
alignment: Alignment.bottomCenter,
|
||
child: Padding(
|
||
padding: const EdgeInsets.only(top: 15, bottom: 15),
|
||
child: Row(
|
||
children: <Widget>[
|
||
sizedBoxWidth(16.w),
|
||
Expanded(
|
||
child: GlassmorphicContainer(
|
||
width: double.infinity,
|
||
height: 50.h,
|
||
borderRadius: 30.r,
|
||
blur: 6,
|
||
alignment: Alignment.bottomCenter,
|
||
border: 0.8,
|
||
linearGradient: LinearGradient(
|
||
begin: Alignment.topLeft,
|
||
end: Alignment.bottomRight,
|
||
colors: [
|
||
const Color(0xFFffffff).withOpacity(0.24),
|
||
const Color(0xFFFFFFFF).withOpacity(0.24),
|
||
],
|
||
// ignore: prefer_const_literals_to_create_immutables
|
||
stops: [
|
||
0.1,
|
||
1,
|
||
]),
|
||
borderGradient: const LinearGradient(
|
||
begin: Alignment.topLeft,
|
||
end: Alignment.bottomRight,
|
||
colors: [
|
||
Color(0xff434A53),
|
||
Color(0xFF434A53),
|
||
],
|
||
),
|
||
child: Center(
|
||
child: TextFormField(
|
||
controller: messageController,
|
||
inputFormatters: [
|
||
RemoveEmojiInputFormatter(),
|
||
],
|
||
obscureText: false,
|
||
style: TextStyle(
|
||
fontSize: 16.sp,
|
||
color: Colors.white,
|
||
),
|
||
autovalidateMode:
|
||
AutovalidateMode.onUserInteraction,
|
||
decoration: InputDecoration(
|
||
contentPadding:
|
||
const EdgeInsets.all(10.0),
|
||
// filled: true,
|
||
// fillColor: Color(0XFF434A53),
|
||
border: InputBorder.none,
|
||
hintStyle: TextStyle(
|
||
fontSize: 14.sp,
|
||
color: const Color(0XFFFCFCFC)
|
||
.withOpacity(0.80),
|
||
fontWeight: FontWeight.w400,
|
||
fontFamily: 'Helvetica'),
|
||
hintText: "Type your message",
|
||
suffixIcon: messageController
|
||
.text.isNotEmpty ||
|
||
isImageAdded == true
|
||
? GestureDetector(
|
||
// onTap: () => _chatItemsAdd(),
|
||
onTap: _sendMessage,
|
||
// () {
|
||
// setState(() {
|
||
// // UploadData();
|
||
// messageController.clear();
|
||
// });
|
||
// },
|
||
// => UploadData(),
|
||
|
||
child: Padding(
|
||
padding: EdgeInsets.only(
|
||
right: 8.w,
|
||
top: 2.h,
|
||
bottom: 2.h),
|
||
child: Container(
|
||
width: 45.w,
|
||
height: 30.h,
|
||
decoration: BoxDecoration(
|
||
color:
|
||
const Color(0xFFD90B2E),
|
||
borderRadius:
|
||
BorderRadius
|
||
.circular(
|
||
30.r)),
|
||
child: const Center(
|
||
child: Icon(
|
||
Icons.send_outlined,
|
||
color: Colors.white,
|
||
)
|
||
// Text(
|
||
// 'Send',
|
||
// style: TextStyle(
|
||
// color: Colors.white,
|
||
// fontSize: 16.sp),
|
||
// )
|
||
)),
|
||
),
|
||
)
|
||
: IconButton(
|
||
onPressed: () {
|
||
ImageUploadBottomSheet()
|
||
.showModal(
|
||
context,
|
||
true,
|
||
(result) {
|
||
attachimage = result;
|
||
var filenameresult =
|
||
extractFileName(result);
|
||
|
||
messageController.text =
|
||
filenameresult;
|
||
setState(() {
|
||
isImageAdded = true;
|
||
});
|
||
},
|
||
);
|
||
},
|
||
icon: Icon(
|
||
Icons.attach_file,
|
||
color: Colors.white,
|
||
size: 23.h,
|
||
),
|
||
),
|
||
),
|
||
minLines: 1,
|
||
maxLines: 1,
|
||
onChanged: (text) {
|
||
setState(() {});
|
||
},
|
||
),
|
||
),
|
||
),
|
||
),
|
||
sizedBoxWidth(12.w),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
],
|
||
)),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
}
|
||
|
||
class ChatMessage {
|
||
String messageContent;
|
||
String messageType;
|
||
bool isread;
|
||
String image;
|
||
ChatMessage({
|
||
required this.messageContent,
|
||
required this.messageType,
|
||
required this.isread,
|
||
required this.image,
|
||
});
|
||
}
|