Skip to content
This repository has been archived by the owner on Apr 10, 2024. It is now read-only.

Commit

Permalink
feat(broadcast, chats): search notes in broadcast, chats sorted by ne…
Browse files Browse the repository at this point in the history
…west messages
  • Loading branch information
RCR0101 committed Apr 7, 2024
1 parent 799dd86 commit aaefdca
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 45 deletions.
67 changes: 43 additions & 24 deletions lib/chat_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,56 @@ class UsersListPage extends StatefulWidget {
_UsersListPageState createState() => _UsersListPageState();
}

class UserWithLastMessage {
final User_D user;
final Timestamp lastMessageTimestamp;

UserWithLastMessage({required this.user, required this.lastMessageTimestamp});
}

class _UsersListPageState extends State<UsersListPage> {
Future<List<User_D>> getUsersWithNonEmptyChats() async {
Future<List<UserWithLastMessage>> getUsersWithNonEmptyChats() async {
final currentUser = FirebaseAuth.instance.currentUser;
if (currentUser == null) return [];

QuerySnapshot userSnapshot =
await FirebaseFirestore.instance.collection('users').get();
List<User_D> allUsers = userSnapshot.docs
.map((doc) => User_D(

List<UserWithLastMessage> usersWithLastMessage = [];

for (var doc in userSnapshot.docs) {
String chatId = determineChatId(currentUser.uid, doc.id);

// Fetch the most recent message for this chat
var messagesSnapshot = await FirebaseFirestore.instance
.collection('chats')
.doc(chatId)
.collection('messages')
.orderBy('timestamp', descending: true)
.limit(1)
.get();

// If chat is not empty, add user and the timestamp of the last message
if (messagesSnapshot.docs.isNotEmpty) {
var lastMessageTimestamp =
messagesSnapshot.docs.first.data()['timestamp'] as Timestamp;
usersWithLastMessage.add(UserWithLastMessage(
user: User_D(
id: doc.id,
name: doc['name'],
email: doc['email'],
imageUrl: doc['imageUrl']))
.toList();

// List to keep track of users with non-empty chats
List<User_D> usersWithNonEmptyChats = [];

// Check each user for non-empty chat
for (var user in allUsers) {
String chatId = determineChatId(currentUser.uid, user.id);
final chatRef =
FirebaseFirestore.instance.collection('chats').doc(chatId);
final snapshot = await chatRef.collection('messages').limit(1).get();

if (snapshot.docs.isNotEmpty) {
usersWithNonEmptyChats.add(user);
imageUrl: doc['imageUrl'],
),
lastMessageTimestamp: lastMessageTimestamp,
));
}
}

return usersWithNonEmptyChats;
// Sort the users based on the timestamp of the last message
usersWithLastMessage.sort(
(a, b) => b.lastMessageTimestamp.compareTo(a.lastMessageTimestamp));

return usersWithLastMessage;
}

@override
Expand Down Expand Up @@ -81,7 +100,7 @@ class _UsersListPageState extends State<UsersListPage> {
)
],
),
body: FutureBuilder<List<User_D>>(
body: FutureBuilder<List<UserWithLastMessage>>(
future: getUsersWithNonEmptyChats(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
Expand All @@ -98,14 +117,14 @@ class _UsersListPageState extends State<UsersListPage> {
itemBuilder: (context, index) {
final user = users[index];
String chatId = determineChatId(
FirebaseAuth.instance.currentUser!.uid, user.id);
FirebaseAuth.instance.currentUser!.uid, user.user.id);
return ListTile(
leading: Stack(
clipBehavior: Clip
.none, // Allows the badge to go outside the Stack's bounds
children: [
CircleAvatar(
backgroundImage: NetworkImage(user.imageUrl),
backgroundImage: NetworkImage(user.user.imageUrl),
backgroundColor: Colors.transparent,
),
Positioned(
Expand Down Expand Up @@ -141,14 +160,14 @@ class _UsersListPageState extends State<UsersListPage> {
),
],
),
title: Text(toCapitalCase(user.name)),
title: Text(toCapitalCase(user.user.name)),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => BlocProvider<ChatBloc>(
create: (context) => ChatBloc(DatabaseRepository()),
child: ChatPage(userId: user.id, chatId: chatId),
child: ChatPage(userId: user.user.id, chatId: chatId),
),
),
);
Expand Down
9 changes: 8 additions & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
//import 'package:onesignal_flutter/onesignal_flutter.dart';
import 'package:padhaihub_v2/bloc/notes_bloc/notes_bloc.dart';
import 'package:padhaihub_v2/bloc/notes_bloc/notes_event.dart';
import 'package:padhaihub_v2/bloc/sign_in_bloc/sign_in_bloc.dart';
Expand All @@ -16,9 +17,9 @@ import 'bloc/overview_bloc/overview_event.dart';
import 'home.dart';

void main() async {
// Initialize Firebase (if you haven't already)
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// initOneSignal();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((_) {
runApp(App());
Expand Down Expand Up @@ -69,3 +70,9 @@ class AuthenticationWrapper extends StatelessWidget {
: MyHomePage(title: 'PadhaiHub');
}
}

// void initOneSignal() {
// OneSignal.initialize(
// "d18400c9-5690-4e47-a6a1-d8fa1ac45ce1",
// );
// }
57 changes: 51 additions & 6 deletions lib/notes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,28 @@ import 'bloc/notes_bloc/notes_bloc.dart';
import 'dart:io';
import 'bloc/notes_bloc/notes_event.dart';

class MyNotesPage extends StatelessWidget {
class MyNotesPage extends StatefulWidget {
const MyNotesPage({super.key});

@override
Widget build(BuildContext context) {
final Size screenSize = MediaQuery.of(context).size;
State<MyNotesPage> createState() => _MyNotesPageState();
}

class _MyNotesPageState extends State<MyNotesPage> {
List<types.FileMessage> allPdfMessages = [];
List<types.FileMessage> filteredPdfMessages = [];
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
context.read<BroadcastBLoC>().add(FetchPdfsEvent());
BlocProvider.of<BroadcastBLoC>(context).add(FetchPdfsEvent());
});
}

@override
Widget build(BuildContext context) {
final Size screenSize = MediaQuery.of(context).size;

return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
Expand Down Expand Up @@ -54,6 +67,33 @@ class MyNotesPage extends StatelessWidget {
body: SafeArea(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
maxLines: 1,
decoration: InputDecoration(
isDense: true,
hintText: "Search PDFs",
fillColor: Colors.white,
filled: true,
prefixIcon: Icon(Icons.search),
contentPadding: EdgeInsets.all(10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25),
borderSide: BorderSide.none,
),
),
onChanged: (searchText) {
setState(() {
filteredPdfMessages = allPdfMessages.where((pdfMessage) {
return pdfMessage.id
.toLowerCase()
.contains(searchText.toLowerCase());
}).toList();
});
},
),
),
SizedBox(
height: screenSize.height * 0.01,
),
Expand Down Expand Up @@ -96,6 +136,11 @@ class MyNotesPage extends StatelessWidget {
if (state is BroadcastError) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(state.message)));
} else if (state is BroadcastPdfListUpdated) {
setState(() {
allPdfMessages = state.pdfMessages;
filteredPdfMessages = List.from(state.pdfMessages);
});
}
},
builder: (context, state) {
Expand All @@ -106,9 +151,9 @@ class MyNotesPage extends StatelessWidget {
onRefresh: () => _refreshContent(context),
child: ListView.builder(
physics: AlwaysScrollableScrollPhysics(),
itemCount: state.pdfMessages.length,
itemCount: filteredPdfMessages.length,
itemBuilder: (context, index) {
final fileMessage = state.pdfMessages[index];
final fileMessage = filteredPdfMessages[index];
return FutureBuilder<String>(
future: getUserProfileImageUrl(fileMessage.author.id),
builder: (context, snapshot) {
Expand Down
44 changes: 30 additions & 14 deletions lib/overview.dart
Original file line number Diff line number Diff line change
Expand Up @@ -190,18 +190,30 @@ class _OverviewSectionState extends State<OverviewSection>
return Expanded(
child: RefreshIndicator(
onRefresh: () => _refreshContent(context),
child: SingleChildScrollView(
physics: AlwaysScrollableScrollPhysics(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizedBox(height: 20), // Use fixed size for consistency
_buildTitle(sidePadding),
SizedBox(height: upPadding * 0.5),
_buildOverviewMessages(sidePadding, upPadding),
_buildOverviewNotes(sidePadding, upPadding),
],
),
child: LayoutBuilder(
// Use LayoutBuilder to ensure SingleChildScrollView takes the full height
builder: (context, constraints) {
return SingleChildScrollView(
physics: AlwaysScrollableScrollPhysics(),
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: constraints.maxHeight,
),
child: IntrinsicHeight(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizedBox(height: 20),
_buildTitle(sidePadding),
SizedBox(height: upPadding * 0.5),
_buildOverviewMessages(sidePadding, upPadding),
_buildOverviewNotes(sidePadding, upPadding),
],
),
),
),
);
},
),
),
);
Expand Down Expand Up @@ -280,7 +292,10 @@ class _OverviewSectionState extends State<OverviewSection>
size: 32, color: Colors.green),
title: Text(
"New Notes",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize:
MediaQuery.of(context).size.width > 360 ? 18 : 16),
),
),
Positioned(
Expand Down Expand Up @@ -336,7 +351,8 @@ class _OverviewSectionState extends State<OverviewSection>
"Unread Messages",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
fontSize:
MediaQuery.of(context).size.width > 360 ? 18 : 16,
),
),
),
Expand Down
8 changes: 8 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.0"
onesignal_flutter:
dependency: "direct main"
description:
name: onesignal_flutter
sha256: "3b60033764e84b9a11a331f290eb21d569e94aeb260df5420fb8a5e073e51b7a"
url: "https://pub.dev"
source: hosted
version: "5.1.3"
open_filex:
dependency: "direct main"
description:
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ dependencies:
dio: ^5.4.2
path_provider: ^2.1.2
cloud_functions: ^4.6.10
onesignal_flutter: ^5.1.3

dev_dependencies:
flutter_test:
Expand Down

0 comments on commit aaefdca

Please sign in to comment.