I have had tough luck with the StreamUnreadIndicator() within the getStream API. I am trying to essentially have an indicator on the list tile for whenever a new message comes in. But nothing returns. I tried putting some debug prints to at least get the number of unread messages for the channel, but it is always 0.
Here's my message list view:
Widget _messagesList(List<dynamic>? messages, StreamChatClient client,
int messageCount, bool friendsTab) {
return ListView.separated(
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
itemCount: messageCount,
itemBuilder: (context, index) {
//print("messaging:"+messages![index].channel);
return GestureDetector(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) =>
MessageApi(
sourceType: SourceType.justMet,
receiverUser: friendsTab ? friends[index] : chatRequesters[index],
userName: userName,
channelId: messages![index].channel,
streamToken: streamToken,
client: StreamChatCore.of(context).client,
)
));
},
child: ListTile(
title: friendsTab ? Text(friends[index].firstName) : Text(chatRequesters[index].firstName),
subtitle: _buildLastMessage(messages![index].channel, client),
trailing: Column(
children: [
StreamUnreadIndicator(
cid: "messaging:"+messages[index].channel,
),
_buildLastMessageAt(messages[index].channel, client),
],
),
leading: CircleAvatar(
radius: 30,
backgroundImage: CachedNetworkImageProvider(
friendsTab ? friends[index].photoUrl : chatRequesters[index].photoUrl
),
),
),
);
},
separatorBuilder: (context, index) {
return const Divider();
},
);
}
Version 4.3 of Stream Chat Flutter introduced unreadMessagesSeparatorBuilder:
Try
StreamMessageListView(
unreadMessagesSeparatorBuilder: (context, unreadCount) =>
Text('$unreadCount unread message'),
)
See the changeling for additional details: https://pub.dev/packages/stream_chat_flutter/changelog
They seem to have updated their backend and now it works without me changing anything. I noticed they changed their docs recently too after this question.
Related
I am creating a slider where I want to show json data in carousel slider the data will be coming from API ofcourse
What are the steps need for that can you guys guide me like have to create http method to first read data.
CarouselSlider(
options: CarouselOptions(
aspectRatio: 1.5,
viewportFraction: 0.95,
enlargeStrategy: CenterPageEnlargeStrategy.height,
enlargeCenterPage: true,
reverse: false,
enableInfiniteScroll: true,
autoPlay: true,
autoPlayAnimationDuration: const Duration(milliseconds: 900),
initialPage: initialPage,
onPageChanged: (index, reason) {
setState(() {
initialPage = index;
debugPrint('$initialPage');
});
}),
items: Category.categories
.map((category) => HeroCarouselCard(category: category))
.toList(),
),
This is something I was firstly doing Category.categories is another equatable class where I was storing static data.
[
{
"CarouselName": "Others",
"CarouselDescription": "A smartphone and tablet-based solution to register and report Factory Assembly Line Inspection information.",
"CarouselImage": "banner3.png"
},
{
"CarouselName": "Production",
"CarouselDescription": "Grow your business",
"CarouselImage": "banner1.jpg"
}
]
following is the json that I wanna use
If I get a complete example would be great for me dont't wanna use getx
The best and easy way is to create a future builder and in future pass the api call in my case I have used http request to fetch all the data.
Container(
margin: const EdgeInsets.symmetric(
horizontal: 10, vertical: 10),
width: MediaQuery.of(context).size.width,
child: FutureBuilder(
future: future,
builder: (context, snapshot) {
final items = snapshot.data;
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return const Center(
child: RepaintBoundary(
child: HomeCardShimmerEffect()),
);
default:
if (snapshot.hasError) {
return Center(
child: Column(
children: [
const Text(
'Something went Wrong Please try again'),
const SizedBox(
height: 5,
),
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const BottomNavBar()));
},
child: const Text('Try Again'))
],
));
} else {
return HomeCardWidget(items: items!);
}
}
}),
)
Step 2:
Is to use Carousel.Builder instead of Carousel Simple and pass it items builder
and else it will work same as the data you show in listview.builder or gridview.builder
Passing context and fetching data according to that.
Hopefully this will be helpfull.
I was following this tutorial https://www.youtube.com/watch?v=wHIcJDQbBFs&t= and got it working so I can send messages and it is stored as follows
chats/targetUid/messages/message
when I send a message it works and I can see them but if I sign into the account im sending it to they cannot see it. I believe its due to the following reasons.
In the tutorial you get data from the targets messages so when I open the chat its getting it from his Uid as the target but when he opens it it uses my Uid as the target.
This is my send message code.
//create Comment
Message newMessage = Message(
profImage: myProfilePic,
username: myName,
uid: myUid,
message: message,
createdAt: DateTime.now(),
);
final refMessages = _firestore.collection('chats/$targetUid/messages');
await refMessages.add(
newMessage.toJson(),
);
The code to open the message.
return ListView.builder(
itemCount: (snapshot.data! as dynamic).docs.length,
itemBuilder: (context, index) {
return InkWell(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ChatScreen(
uid: (snapshot.data! as dynamic).docs[index]['uid'],
),
),
);
},
child: ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(
(snapshot.data! as dynamic).docs[index]['photoUrl'],
),
),
title: Text(
(snapshot.data! as dynamic).docs[index]['username'],
),
),
);
},
);
I fixed it by creating a groupchat Id and storing it in firestore that way rather than the targets Uid. this is the method im using to create the groupchat Id.
String chatroomId(String user1, String user2) {
if (user1[0].toLowerCase().codeUnits[0] >
user2.toLowerCase()[0].codeUnits[0]) {
return "$user1$user2";
} else {
return "$user2$user1";
}
}
I'm new to flutter and I want to use list view using flutter list view builder.
I used this data model(user.equipments) to build the list view
in here equipmentName comming from equipment model as show following
Here is the actual issue, I need to buind the equipment name from equipment model instead of buinding this id "1603739590802". I tried few ways, but those were not woking as expected.
here is the current result
here is my code for list view builder
Container(
width: size.width,
child: ListView.builder(
shrinkWrap: true,
itemCount: _user.getSingleUser.equipments.length,
itemBuilder: (context, index) {
return ListTile(
tileColor: Colors.blue[100],
onTap: () {
_addModalBottomSheet(bc,size,_user.getSingleUser.equipments[index].id);
},
leading:Icon(Icons.fiber_manual_record_rounded),
trailing: IconButton(
onPressed: () {
singleUser.equipments.removeAt(index);
_user.setSingleUser(singleUser);
},
icon: Icon(
Icons.close_outlined,
color: Colors.red,
),
iconSize: 20,
),
title: Text(
'${_user.getSingleUser.equipments[index].equipmentName} :
${_user.getSingleUser.equipments[index].yearsOfUsing} years',
),
);
},
),
),
Any suggestion would be appreciated.
Assuming equipmentList is the list of equipments :
equipmentList.firstWhere(
(e) => e.id == _user.getSingleUser.equipments[index].equipmentName).name
The name equipmentName is misleading, it should be equipmentId.
I am trying to filter a listview. I am able to see that data is filtered but I don't get anything at the screen. Probably it is just a simple thing.
Part of the code:
final messageBubble = MessageBubble(
document: nameDocument,
name: gaName,
);
messageBubbles.add(messageBubble);
filtermessageBubbles= messageBubbles;
(...)
FloatingSearchBar.builder(
pinned: true,
itemCount: filtermessageBubbles.length,
padding: EdgeInsets.only(top: 10.0),
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: filtermessageBubbles[index],
);
},
onChanged: (String value) {
setState(() {
filtermessageBubbles = messageBubbles.where((item) => item.name.toLowerCase().contains(value.toLowerCase())).toList();
print(filtermessageBubbles.length);
print(filtermessageBubbles);
});
},
and when I run it, I am able to see that filteredmessageBubbler.length reduces its number, but I don't see any change in the virtual device.
Thanks in advance!
I want to add a checkbox for GirdView in Flutter. The data was fetched from API request include attribute selected default is false. When I click on the checkbox of each Item it will change value is True and update on UI and I use Mobx to observe these change actions. When I debugging the values were changed but UI didn't update, I really don't know the reason. I added 2 pictures for UI and Mobx model below.
API:
{
"name": "HuynhDuy Phuc",
"birthday": "None",
"phone": "N/A",
"isSelected": false
},
{
"name": "Doan Phuc",
"birthday": "None",
"phone": "N/A",
"isSelected": false
},
{
"name": "Phuc Vu",
"birthday": "None",
"phone": "N/A",
"isSelected": false
},
final _userApiPresenter = Provider.of<UserApiPresenter>(context);
_userApiPresenter.fetchUsersList();
Observer(
name: 'ListHomePage',
builder: (BuildContext context) {
return (_userApiPresenter.userAPI != null)
? AnimationLimiter(
child: GridView.builder(
physics: BouncingScrollPhysics(),
padding: EdgeInsets.all(12),
addAutomaticKeepAlives: true,
//Determine the number of cells per row
gridDelegate:
new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemCount:
_userApiPresenter.userAPI.users.length,
itemBuilder: (context, index) {
User user =
_userApiPresenter.getUser(index: index);
return AnimationConfiguration.staggeredGrid(
position: index,
duration:
const Duration(milliseconds: 375),
columnCount: 2,
child: Container(
child: ScaleAnimation(
child: GestureDetector(
child: Stack(
children: <Widget>[
UserItem(
name: user.name,
type: user.name,
phone: user.phone,
birthday: user.birthday,
isSelected: user.selected,
),
Align(
alignment: Alignment.topRight,
child: Checkbox(
value: user.selected,
onChanged: (_) {
if(user.selected){
_userApiPresenter.changeStatusCheckBox(index: index);
} else{
_userApiPresenter.changeStatusCheckBox(index: index);
}
},
),
),
],
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder:
(BuildContext context) =>
UserDetailPage(
index: index,
name: user.name,
),
),
);
},
),
),
),
);
},
),
)
: Center(
child: CircularProgressIndicator(),
);
},
)
UI
Mobx model
Observable information about users array and the user model itself is missing, but what you need to do(if already not) is:
Make the array of users observable as well - this way any addition, deletion, etc will results in update of the number of user boxes in the UI
Make property selected of User observable also - this way when certain user 'selected' state is effected, the UI will render the change
And something off topic:
You don't need #action attribute on getUser method, because this method is not updating any observable data
If this answer does not solve your problem, please provide implementation of userApi and User :)
You just missing one thing.
mobX does not update UI unless you tell it main variable changed..
To do so, just add the following line of code to your changeStatusCheckBox()
_userAPI = _userAPI;