Skip to content

Instantly share code, notes, and snippets.

@dunods
Created May 27, 2021 18:08
Show Gist options
  • Save dunods/00fbf75b60ddd408bee4f1f31e238dc4 to your computer and use it in GitHub Desktop.
Save dunods/00fbf75b60ddd408bee4f1f31e238dc4 to your computer and use it in GitHub Desktop.
backup
import 'dart:async';
import 'package:aclub/features/chat/bloc/message.dart';
import 'package:aclub/features/chat/model/message.dart';
import 'package:aclub/features/chat/provider/group_provider.dart';
import 'package:aclub/features/chat/screen/chat/info.dart';
import 'package:aclub/features/chat/screen/chat/search.dart';
import 'package:aclub/features/chat/utils/constant.dart';
import 'package:aclub/features/chat/utils/styles.dart';
import 'package:aclub/src/model/SessionProfile.dart';
import 'package:aclub/utils/Consts/ApiConst.dart';
import 'package:aclub/utils/MyLoader.dart';
import 'package:flutter/material.dart';
import 'package:aclub/features/chat/screen/chat/input.dart';
import 'package:aclub/features/chat/screen/chat/thread.dart';
import 'package:focused_menu/modals.dart';
import 'package:grouped_list/grouped_list.dart';
import 'package:jiffy/jiffy.dart';
import 'package:swipe_to/swipe_to.dart';
import 'package:focused_menu/focused_menu.dart';
import 'package:aclub/features/chat/bloc/chat.dart';
import 'package:animate_do/animate_do.dart';
import 'dart:math';
class ChatView extends StatefulWidget {
int roomId;
int userId;
int cbId;
SessionProfile profile;
ChatView({this.roomId, this.userId, this.cbId, this.profile});
@override
_ChatViewState createState() => _ChatViewState();
}
class _ChatViewState extends State<ChatView> {
GroupProvider groupProvider = GroupProvider();
final focusNode = FocusNode();
Message replyMessage;
ChatBloc chatBloc = new ChatBloc();
// ChatBloc chatBloc = new ChatBloc();
MessageBloc messageBloc = new MessageBloc();
ScrollController _scrollController = ScrollController();
String lastCursor;
int lenghtMs;
String cursorCache;
bool _closePinned = true;
AnimationController animateController;
double _pinnedHeight = 40;
String _roomTitle = 'Chat';
String _roomImage;
int _scrollIndex;
int faker = 0;
List pinnedMessage = [];
var preoffset;
bool loading = false;
bool _showJump = false;
void scrollToLast() {
print("trying to scroll");
Future.delayed(Duration.zero, () {
_scrollController.animateTo(
(lenghtMs + 1 / lenghtMs) *
_scrollController.position.minScrollExtent,
duration: const Duration(milliseconds: 300),
curve: Curves.easeOut);
});
// WidgetsBinding.instance.addPostFrameCallback((_) {
// });
}
void reload() async {}
Widget pinnedIcon = Icon(Icons.keyboard_arrow_down);
void expander() async {
if (_pinnedHeight == 40) {
setState(() {
_pinnedHeight = 300;
pinnedIcon = Icon(Icons.keyboard_arrow_up);
});
} else if (_pinnedHeight == 300) {
setState(() {
_pinnedHeight = 40;
pinnedIcon = Icon(Icons.keyboard_arrow_down);
});
}
}
void jumpToMessage(messageId) async {
await chatBloc.jumpId(widget.roomId, messageId);
setState(() {
widget.cbId = messageId;
// _closePinned = false;
});
WidgetsBinding.instance.addPostFrameCallback((_) {
_scrollController.animateTo(
_scrollController.position.maxScrollExtent * 1.2,
duration: const Duration(milliseconds: 100),
curve: Curves.easeOut);
});
}
void setScroll(index) async {
jumpTest(index);
}
void jumpTest(index) async {
// WidgetsBinding.instance.addPostFrameCallback((_) async {
_scrollController.animateTo(
_scrollController.position.maxScrollExtent * 0.95,
duration: const Duration(milliseconds: 100),
curve: Curves.easeOut);
// });
}
@override
void initState() {
_scrollInit();
initChat();
super.initState();
focusNode.addListener(_onFocusChange);
}
void _onFocusChange() {
if (focusNode.hasFocus) {
setState(() {
_showJump = true;
});
} else {
setState(() {
_showJump = false;
});
}
}
@override
void dispose() {
chatBloc.createCheckpoint(widget.userId, widget.roomId);
super.dispose();
}
_single(content) {
content.removeWhere((person) => person['user']['id'] == widget.userId);
return content[0]['user'];
}
void initChat() async {
groupInfo();
// chatBloc.pinnedByRoom(widget.roomId);
if (widget.cbId != null) {
jumpToMessage(widget.cbId);
} else {
await chatBloc.initChat(widget.roomId, null);
// await chatBloc.getMessageCursor(widget.roomId, '', widget.userId);
}
chatBloc.chatSubscription(widget.roomId);
}
void groupInfo() async {
var room = await groupProvider.getGroup(widget.roomId);
// print(room['participants']['participants']);
if (room['type'] == 'GROUP') {
setState(() {
_roomTitle = room['name'];
_roomImage = ChatConst.public_url + '${room['image']}';
});
} else {
var user = await _single(room['participants']['participants']);
setState(() {
_roomTitle = user['member']['member_displayname'];
_roomImage = ApiConst.profile_image_path +
'${user['member']['member_profile_image']}';
});
}
getPinned();
// var getPinned = await chatBloc.pinnedByRoom(widget.roomId);
// setState(() {
// pinnedMessage = getPinned;
// });
}
void getPinned() async {
var getPinned = await chatBloc.pinnedByRoom(widget.roomId);
setState(() {
pinnedMessage = getPinned;
});
}
void jumpLast() async {
chatBloc.clear();
await chatBloc.initChat(widget.roomId, null);
_scrollController.animateTo(_scrollController.position.minScrollExtent,
duration: const Duration(milliseconds: 100), curve: Curves.easeOut);
}
_filter(String query) async {
// userBloc.userFilter(query);
// chatBloc.userFilter(query);
}
_scrollInit() {
_scrollController.addListener(() async {
if (_showJump == false) {
setState(() {
_showJump = true;
});
}
print('pos ${_scrollController.position.pixels}');
print('min ${_scrollController.position.minScrollExtent * 0.7}');
print('max ${_scrollController.position.maxScrollExtent}');
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
await chatBloc.lastById(widget.roomId);
}
if (_scrollController.position.pixels ==
_scrollController.position.minScrollExtent
// _scrollController.position.maxScrollExtent -
// _scrollController.position.pixels >=
// 100
) {
setState(() {
loading = true;
});
preoffset = _scrollController.position.extentAfter;
// setState(() {
// faker = 5;
// });
// jumpFront();
// _scrollController.position.maxScrollExtent;
// setState(() {
// loading = true;
// });
await chatBloc.firstById(widget.roomId);
await chatBloc.chatSubscription(widget.roomId);
setState(() {
loading = false;
});
}
});
}
void jumpFront() {
print(preoffset);
WidgetsBinding.instance.addPostFrameCallback((_) {
// if (_scrollController.hasClients) {
_scrollController
.jumpTo(_scrollController.position.maxScrollExtent - preoffset);
// }
});
setState(() {
faker = 0;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: _buildBar(context),
body: Stack(
children: [
Container(
child: Stack(
children: [
Column(
children: [
Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
color: Color(0xffE5E5E5),
),
child: ClipRRect(
child: listMessage(chatBloc),
),
),
),
ChatInput(
onCancelReply: cancelReply,
replyMessage: replyMessage,
// jumper: jumpLast,
focusNode: focusNode,
userId: widget.userId,
roomId: widget.roomId,
profile: widget.profile,
),
// Positioned(top: 100, right: 0, child: Text('woi'))
],
),
Visibility(
visible: _showJump,
child: Positioned(
bottom: 80,
right: 0,
child: InkWell(
onTap: jumpLast,
child: Container(
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
width: 50.0,
height: 50.0,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
topRight: Radius.circular(0),
bottomLeft: Radius.circular(15),
bottomRight: Radius.circular(0),
),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 2,
blurRadius: 7,
offset: Offset(
0, 3), // changes position of shadow
),
],
),
child: Icon(
Icons.arrow_drop_down_circle_outlined,
color: ChatStyles.baseRed,
),
),
)),
)
],
),
),
if (pinnedMessage.length != 0)
Visibility(
visible: _closePinned,
child: Container(
margin: EdgeInsets.all(8),
padding: EdgeInsets.fromLTRB(10, 5, 10, 5),
width: MediaQuery.of(context).size.width,
color: Color(0xffFFCE3F).withOpacity(0.8),
height: _pinnedHeight,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Wrap(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InkWell(
onTap: expander,
child: Container(
width:
MediaQuery.of(context).size.width,
child: Container(
padding:
EdgeInsets.fromLTRB(0, 0, 0, 5),
child: ListView.builder(
shrinkWrap: true,
itemCount: pinnedMessage.length,
itemBuilder:
(BuildContext context,
int index) {
return InkWell(
onTap: () => {
jumpToMessage(
pinnedMessage[index]
['id']),
expander()
},
child: Container(
// decoration:
// BoxDecoration(
// border: Border(
// bottom: BorderSide(
// color: Colors
// .grey[
// 850])),
// ),
padding:
EdgeInsets.fromLTRB(
0, 4, 0, 4),
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: [
Padding(
padding:
const EdgeInsets
.fromLTRB(
0, 2, 0, 2),
child: Row(
children: [
Padding(
padding:
const EdgeInsets
.fromLTRB(
0,
0,
2,
0),
child: Transform
.rotate(
angle: 90 *
pi /
360,
child: Icon(
Icons
.push_pin,
size: 12,
),
),
),
Container(
constraints:
BoxConstraints(
maxWidth:
200),
child: Text(
'${pinnedMessage[index]['content']}',
maxLines: 1,
overflow:
TextOverflow
.ellipsis,
),
),
],
),
),
Text(
'${pinnedMessage[index]['user']['member']['member_displayname']}',
style: TextStyle(
color: ChatStyles
.baseRed),
),
],
),
),
);
}))),
),
InkWell(
onTap: () => {
setState(() {
_closePinned = false;
}),
},
child: Text(
'Dont Show Again',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w700),
),
)
],
)
],
),
),
Align(
alignment: Alignment.bottomRight,
child: InkWell(
onTap: expander,
child: pinnedIcon,
),
)
],
),
)),
],
)
// )
);
}
Widget listMessage(ChatBloc chatBloc) {
return StreamBuilder(
stream: chatBloc.subject.stream,
builder: (BuildContext context, AsyncSnapshot<List<Message>> snapshot) {
if (snapshot.hasData) {
// if (chatBloc.state.value == 'FETCH') {
if (lastCursor != snapshot.data.last.created_at
// && lenghtMs != snapshot.data.length
) {
lastCursor = snapshot.data.last.created_at;
lenghtMs = snapshot.data.length;
}
// }
// print(lenghtMs);
// print(lastCursor);
return GroupedListView<dynamic, DateTime>(
key: PageStorageKey<String>('chatList'),
semanticChildCount: snapshot.data.length,
controller: _scrollController,
elements: snapshot.data,
reverse: true,
groupBy: (element) => DateTime(
DateTime.parse('${element.created_at}').year,
DateTime.parse('${element.created_at}').month,
DateTime.parse('${element.created_at}').day),
// element.created_at,
groupComparator: (value1, value2) => value1.compareTo(value2),
itemComparator: (item1, item2) => item1.id.compareTo(item2.id),
order: GroupedListOrder.DESC,
useStickyGroupSeparators: false,
groupSeparatorBuilder: (DateTime value) {
if (loading == false)
return Container(
child: Align(
child: Container(
decoration: BoxDecoration(
color: Color(0xffFFCE3F).withOpacity(0.7),
borderRadius:
const BorderRadius.all(Radius.circular(50.0)),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'${Jiffy([
value.year,
value.month,
value.day
]).format('MMM dd')}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12, fontWeight: FontWeight.w700),
),
),
),
),
);
},
indexedItemBuilder: (context, element, index) {
if (widget.cbId != null) {
if (widget.cbId == element.id) {
// setScroll(index);
_scrollIndex = index;
}
}
return FocusedMenuHolder(
child: Column(
children: [
if (loading == false)
(widget.cbId == null || widget.cbId != element.id)
? ChatThread(
onSwipeMessage: (element) {
replyToMessage(element);
// focusNode.requestFocus();
},
userId: widget.userId,
message: element,
jumpToMessage: this.jumpToMessage)
// : (widget.cbId != element.id)
// ? ChatThread(
// onSwipeMessage: (element) {
// replyToMessage(element);
// // focusNode.requestFocus();
// },
// userId: widget.userId,
// message: element,
// jumpToMessage: this.jumpToMessage)
: BounceInLeft(
controller: (controller) => animateController,
manualTrigger: true,
animate:
widget.cbId == element.id ? true : false,
child: ChatThread(
onSwipeMessage: (element) {
replyToMessage(element);
// focusNode.requestFocus();
},
userId: widget.userId,
message: element,
jumpToMessage: this.jumpToMessage),
),
if (loading == true) MyLoader()
],
),
menuWidth: MediaQuery.of(context).size.width * 0.50,
blurSize: 5.0,
menuItemExtent: 45,
menuOffset:
10.0, // Offset value to show menuItem from the selected item
bottomOffsetHeight: 100.0,
menuBoxDecoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.all(Radius.circular(15.0))),
duration: Duration(milliseconds: 50),
animateMenuItems: true,
menuItems: <FocusedMenuItem>[
FocusedMenuItem(
title: Text("Reply"),
trailingIcon: Icon(Icons.reply),
onPressed: () async {
replyToMessage(element);
}),
FocusedMenuItem(
title: Text("Pinned"),
trailingIcon: Icon(
Icons.star,
color: Colors.yellow[700],
),
onPressed: () async {
await messageBloc.updateMessageById(
element.id, true, null);
getPinned();
}),
if (element.user_id == widget.userId)
FocusedMenuItem(
title: Text(
"Delete",
style: TextStyle(color: Colors.redAccent),
),
trailingIcon: Icon(
Icons.delete,
color: Colors.redAccent,
),
onPressed: () async {
await messageBloc.updateMessageById(
element.id, null, true);
}),
],
onPressed: null,
);
});
}
return Center(child: MyLoader());
});
}
void cancelReply() async {
jumpLast();
setState(() {
replyMessage = null;
});
}
void replyToMessage(Message message) {
setState(() {
replyMessage = message;
});
}
//search bar util
final TextEditingController _search = new TextEditingController();
Icon _searchIcon = new Icon(Icons.search);
Widget _appBarTitle = new InkWell(
child: Container(
padding: EdgeInsets.all(5),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CircleAvatar(
radius: 25,
backgroundColor: Colors.transparent,
child: Container(
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(50)),
width: 50,
height: 50,
child: Icon(
Icons.person,
color: Colors.grey[800],
),
),
),
Column(children: [Text('chat')])
],
),
),
);
// Text(
// 'Chat',
// style: TextStyle(color: Colors.black, fontSize: 16),
// );
//custom appbar
Widget _buildBar(BuildContext context) {
return new AppBar(
centerTitle: false,
// title: _appBarTitle,
automaticallyImplyLeading: false,
flexibleSpace: SafeArea(
child: Container(
padding: EdgeInsets.only(right: 16),
child: Row(
children: <Widget>[
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(
Icons.arrow_back,
color: Color(0xffFBA53F),
),
),
SizedBox(
width: 2,
),
InkWell(
onTap: () => {
// Navigator.of(context).push(
// MaterialPageRoute(
// builder: (context) => ChatInfo(
// roomId: widget.roomId,
// userId: widget.userId,
// )),
// )
},
child: Container(
child: CircleAvatar(
backgroundColor: Colors.grey[300],
backgroundImage: NetworkImage("${_roomImage}"),
maxRadius: 20,
),
)),
SizedBox(
width: 12,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"${_roomTitle}",
style:
TextStyle(fontSize: 14, fontWeight: FontWeight.w600),
),
],
),
),
IconButton(
icon: _searchIcon,
onPressed: () => {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => ChatSearch(
roomId: widget.roomId,
userId: widget.userId,
)),
)
},
color: Color(0xffF6403E),
),
IconButton(
icon: Icon(
Icons.menu,
color: Color(0xffF6403E),
),
onPressed: () => {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ChatInfo(
roomId: widget.roomId,
userId: widget.userId,
profile: widget.profile,
)),
)
},
color: Color(0xffF6403E),
)
],
),
),
),
// actions: [
// IconButton(
// icon: _searchIcon,
// onPressed: () => {
// Navigator.of(context).push(
// MaterialPageRoute(
// builder: (context) => ChatSearch(
// roomId: widget.roomId,
// userId: widget.userId,
// )),
// )
// },
// color: Color(0xffF6403E),
// ),
// // IconButton(
// // icon: Icon(
// // Icons.menu,
// // color: Color(0xffF6403E),
// // ),
// // onPressed: null,
// // color: Colors.black),
// PopupMenuButton<String>(
// icon: Icon(
// Icons.menu,
// color: Color(0xffF6403E),
// ),
// onSelected: handleClick,
// itemBuilder: (BuildContext context) {
// return {'Search', 'Info'}.map((String choice) {
// return PopupMenuItem<String>(
// value: choice,
// child: Text(
// choice,
// style: TextStyle(color: Colors.black, fontSize: 12),
// ),
// );
// }).toList();
// },
// ),
// ],
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Color(0xffFBA53F)),
);
}
void handleClick(String value) {
switch (value) {
case 'Search':
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ChatSearch(
roomId: widget.roomId,
userId: widget.userId,
)),
);
break;
case 'Info':
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => ChatInfo()),
);
break;
}
}
//appbar search function
void _searchPressed() {
setState(() {
if (this._searchIcon.icon == Icons.search) {
this._searchIcon = new Icon(
Icons.close,
color: Color(0xffF6403E),
);
this._appBarTitle = new TextField(
controller: _search,
onChanged: _filter,
decoration: new InputDecoration(
prefixIcon: new Icon(
Icons.search,
color: Color(0xffF6403E),
),
hintText: 'Search...'),
);
} else {
this._searchIcon = new Icon(Icons.search);
this._appBarTitle = new Text(
'Chat',
style: TextStyle(color: Colors.black, fontSize: 16),
);
_search.clear();
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment