Reputation: 327
I am returning a stream from Firestore. I want to sort results by date and display in Week 1, Week 2 etc.
However I only want to display Week 1, Week 2 etc. only once with the relevant number of sorted items displaying underneath. At the moment it displays for every item returned in stream and I do not want this.
It currently looks like this, but I do not want Week 2 to display multiple times only once:
class UserReflections extends StatefulWidget {
final String? myString;
const UserReflections({Key? key, this.myString}) : super(key: key);
@override
_UserReflectionsState createState() => _UserReflectionsState();
}
class _UserReflectionsState extends State<UserReflections> {
late final Stream<QuerySnapshot> _usersStream;
Color cardColor = Color(0xFFEDAF99);
Color sage = Color(0xFF6f7c6b);
Color rust = Color(0xFFF58500);
Color lavendar = Color(0xFFC2AECD);
Color backgroundColor = Color(0xFFF6F6F6);
Color backgroundColorBlue = Color(0xFFE8EEF3);
Color cardColorOne = Color(0xFFFFE3D3);
Color cardColorTwo = Color(0xFFFFE8EC);
Color cardColorThree = Color(0xFFFFFACA);
Color cardColorFour = Color(0xFFEEE5FF);
Color SliderColor = Color(0xFFEDAF99);
Color purpleColor = Color(0xFFB84DEC);
@override
void initState() {
_usersStream = FirebaseFirestore.instance
.collection('reflection')
.where("uid", isEqualTo: FirebaseAuth.instance.currentUser!.uid)
.orderBy('dateTime', descending: true)
.snapshots();
}
@override
Widget build(BuildContext context) {
final _user = Provider.of<UserListModel>(context).returnToDos;
return StreamBuilder<QuerySnapshot>(
stream: _usersStream,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
print(snapshot.error);
return Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return SliverToBoxAdapter(
child: Center(
child: Text(
"Loading",
style: TextStyle(fontSize: 30, color: Colors.black),
),
),
);
}
return SliverList(
delegate: SliverChildBuilderDelegate(
(context, i) {
DocumentSnapshot documentSnapshot = snapshot.data!.docs[i];
final Timestamp timestamp = documentSnapshot['dateTime'];
final DateTime date = timestamp.toDate();
final dateFormatter = DateFormat('yyyy-MM-dd');
final dateString = dateFormatter.format(date);
final myFormatDateString = DateFormat.yMMMMEEEEd().format(date);
final difference =
date.difference(_user[0].dateTime!.toDate()).inDays;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
difference <= 7
? Padding(
padding: EdgeInsets.only(
top: 10, bottom: 10, left: 20, right: 15),
child: Text('Week 1'),
)
: Padding(
padding: EdgeInsets.only(
top: 10, bottom: 10, left: 20, right: 15),
child: Text("Week 2")),
GestureDetector(
onTap: () {},
child: Padding(
padding: EdgeInsets.only(
top: 10, bottom: 10, left: 15, right: 15),
child: Container(
width: MediaQuery.of(context).size.width / 1.08,
decoration: BoxDecoration(
color: cardColorOne,
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: EdgeInsets.only(
left: 15, top: 15, right: 15, bottom: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
documentSnapshot['tag'],
style: TextStyle(
color: Colors.black,
fontSize: 17,
fontWeight: FontWeight.w600),
),
Align(
alignment: Alignment.centerRight,
child: Padding(
padding: EdgeInsets.only(
top: 2, bottom: 0, right: 5),
child: Image.asset(
'assets/images/sitting.png',
height: 40,
width: 58,
fit: BoxFit.cover)),
),
]),
SizedBox(height: 5),
Text(
myFormatDateString,
style: TextStyle(
color: Colors.black,
fontSize: 13,
fontWeight: FontWeight.w400),
),
SizedBox(height: 10),
Text(
documentSnapshot['reflectionEntry'],
style: TextStyle(
color: Colors.black,
fontSize: 17,
fontWeight: FontWeight.normal),
// maxLines: 3,
// overflow: TextOverflow.ellipsis,
),
SizedBox(
height: 15,
),
// Align(
// alignment: Alignment.centerRight,
// child: Padding(
// padding: EdgeInsets.only(top: 5, bottom: 5),
// child: Image.asset(
// 'assets/images/sitting.png',
// height: 40,
// width: 58,
// fit: BoxFit.cover)),
// ),
]),
),
),
),
),
]);
},
childCount: snapshot.data!.docs.length,
),
);
},
);
}
}
Upvotes: 0
Views: 301
Reputation: 1095
Perhaps something you can try:
Use helper booleans to detect whether it is the first in week 1 (or week 2).
Where you define all the colors, also define 4 booleans.
bool firstWeekOne = false;
bool secondWeekOne = false;
bool firstWeekTwo = false;
bool secondWeekTwo = false;
after
final difference =
date.difference(_user[0].dateTime!.toDate()).inDays;
add
if (difference <= 7) {
if (firstWeekOne) {
secondWeekOne = true;
}
else {
firstWeekOne = true;
}
}
else {
if (firstWeekTwo) {
secondWeekTwo = true;
}
else {
firstWeekTwo = true;
}
}
change
difference <= 7
? Padding(
padding: EdgeInsets.only(
top: 10, bottom: 10, left: 20, right: 15),
child: Text('Week 1'),
)
: Padding(
padding: EdgeInsets.only(
top: 10, bottom: 10, left: 20, right: 15),
child: Text("Week 2")),
into
difference <= 7
? !secondWeekOne ? Padding(
padding: EdgeInsets.only(
top: 10, bottom: 10, left: 20, right: 15),
child: Text('Week 1'),
) : SizedBox.shrink()
: !secondWeekTwo ? Padding(
padding: EdgeInsets.only(
top: 10, bottom: 10, left: 20, right: 15),
child: Text("Week 2"),
) : SizedBox.shrink(),
Upvotes: 1