Skip to content

Commit

Permalink
Merge pull request #23 from ArinNigam/chatroom
Browse files Browse the repository at this point in the history
Chatroom
  • Loading branch information
henilp105 authored Feb 16, 2024
2 parents 195b6ed + 39d9048 commit 1e51975
Show file tree
Hide file tree
Showing 16 changed files with 541 additions and 14 deletions.
4 changes: 3 additions & 1 deletion backend/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ import roomResource from "./resources/rooms/roomResource.js";
import lostAndFoundListResource from "./resources/lostAndFound/lostAndFoundListResource.js";
import studentListResource from "./resources/student/studentListResource.js";
import facultyListResource from "./resources/faculty/facultyListResource.js";
import messageResource from './resources/chatroom/messageListResource.js'

const PORT = `${process.env.PORT || 3000}`;
const app = express();

app.use(logger("dev"));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(cors());

Expand All @@ -40,6 +41,7 @@ app.use("/", testResource);
app.use("/rooms", roomListResource);
app.use("/room", roomResource);
app.use("/lost-and-found", lostAndFoundListResource);
app.use("/messages",messageResource);

app.get("/protected", tokenRequired, (req, res) => {
res.json({ message: "Access granted" });
Expand Down
3 changes: 3 additions & 0 deletions backend/constants/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@ export const tokenVerificationFailed =
"Token verification failed, authorization denied.";
export const invalidUserType = "Invalid user type";
export const tokenUpdateError = "Error updating token";
export const badRequest = "Bad request";
export const notFound = "Not found";
export const deleted = "Deleted";
20 changes: 20 additions & 0 deletions backend/models/message.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import mongoose from "mongoose";

const MessageSchema = new mongoose.Schema({
sender: {
type: String,
required: true
},
content: {
type: String,
required: true
},
timestamp: {
type: Date,
default: Date.now()
}
});

const Message = mongoose.model('Message', MessageSchema);

export default Message;
44 changes: 44 additions & 0 deletions backend/resources/chatroom/messageListResource.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import Message from '../../models/message.js';
import * as messages from "../../constants/messages.js";
import { Router} from "express";
const messageListRouter = Router();

messageListRouter.get("/", async (req, res) => {
try {
const messages = await Message.find({});
res.json(messages);
} catch (err) {
res.status(500).json({ message: messages.internalServerError });
}
});

messageListRouter.post("/", async (req, res) => {
const message = new Message({
sender: req.body.sender,
content: req.body.content,
timestamp: req.body.timestamp
});
try {
const newMessage = await message.save();
res.status(201).json(newMessage);
} catch (err) {
res.status(400).json({ message: messages.badRequest });
}
});

messageListRouter.delete("/:id", async (req, res) => {
try {
const message = await Message.findById(req.params.id);
console.log(message);
if (message) {
await message.deleteOne();
res.json({ message: messages.deleted });
} else {
res.status(404).json({ message: messages.notFound });
}
} catch (err) {
res.status(500).json({ message: messages.internalServerError });
}
});

export default messageListRouter;
2 changes: 1 addition & 1 deletion backend/resources/faculty/facultyListResource.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const facultyListResource = express.Router();

facultyListResource.get("/", async (req, res) => {
try {
const faculties = await Faculty.find().populate("courses");
const faculties = await Faculty.find()
res.json(faculties);
} catch (err) {
res.status(500).json({ message: messages.internalServerError });
Expand Down
8 changes: 4 additions & 4 deletions backend/resources/student/studentListResource.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ const studentListResource = express.Router();
studentListResource.get("/", async (req, res) => {
try {
const students = await Student.find()
.populate("skills")
.populate("achievements");
// .populate("skills")
// .populate("achievements");
res.json(students);
} catch (err) {
res.status(500).json({ message: messages.internalServerError });
Expand All @@ -18,8 +18,8 @@ studentListResource.get("/", async (req, res) => {
studentListResource.post("/", async (req, res) => {
const { email } = req.body;
let existingUser = await Student.findOne({ email })
.populate("skills")
.populate("achievements");
// .populate("skills")
// .populate("achievements");
try {
if (!existingUser) {
const newUser = new Student({ email });
Expand Down
11 changes: 5 additions & 6 deletions backend/resources/student/studentResouce.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,10 @@ studentRouter.put("/:id", async (req, res) => {
studentId,
studentData,
{ new: true }
)
.populate("skills")
.populate("achievements");
);
res.json(updatedStudent);
} catch (error) {
console.log(error);
res.status(500).json({ message: messages.internalServerError });
}
});
Expand All @@ -43,9 +42,9 @@ studentRouter.delete("/:id", async (req, res) => {
const studentId = req.params.id;

try {
const deletedStudent = await Student.findByIdAndDelete(studentId)
.populate("skills")
.populate("achievements");
const deletedStudent = await Student.findByIdAndDelete(studentId);
// .populate("skills")
// .populate("achievements");
res.json(deletedStudent);
} catch (error) {
res.status(500).json({ message: messages.internalServerError });
Expand Down
Binary file added frontend/lib/assets/chatroom_bg.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 6 additions & 2 deletions frontend/lib/components/material_textformfield.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class MaterialTextFormField extends StatelessWidget {
this.contentPadding,
this.hintColor,
this.enabled,
this.controllerLessValue});
this.controllerLessValue,
this.onTap});

final TextEditingController? controller;
final String? Function(String?)? validator;
Expand All @@ -22,6 +23,7 @@ class MaterialTextFormField extends StatelessWidget {
final EdgeInsets? contentPadding;
final bool? enabled;
final String? controllerLessValue;
final Function? onTap;

@override
Widget build(BuildContext context) {
Expand All @@ -30,12 +32,14 @@ class MaterialTextFormField extends StatelessWidget {
substituteController.text = controllerLessValue!;
}
return TextFormField(
onTap: () => onTap != null ? onTap!() : null,
enabled: enabled ?? true,
controller: controller ?? substituteController,
maxLines: 1,
onChanged: (value) => onChanged != null ? onChanged!(value) : null,
validator: (value) => validator != null ? validator!(value) : null,
onFieldSubmitted: (value) => onSubmitted != null ? onSubmitted!(value) : null,
onFieldSubmitted: (value) =>
onSubmitted != null ? onSubmitted!(value) : null,
cursorColor: Colors.teal.shade900,
style: TextStyle(
color: Colors.teal.shade900,
Expand Down
62 changes: 62 additions & 0 deletions frontend/lib/constants/dummy_entries.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../models/course.dart';
import '../models/faculty.dart';
import '../models/lost_and_found_item.dart';
import '../models/mess_menu.dart';
import '../models/message.dart';
import '../models/room.dart';
import '../models/skills.dart';
import '../models/student.dart';
Expand Down Expand Up @@ -1236,3 +1237,64 @@ class DummyAchievements {
];
// You can use the dummyEntries list as needed in your application
}

class DummyMessages {
static List<Message> messages = [
Message(
sender: "Alice",
content: "Hello there!",
timestamp: DateTime.now(),
),
Message(
sender: "Bob",
content: "Hi Alice!",
timestamp: DateTime.now().add(Duration(minutes: 5)),
),
Message(
sender: "Alice",
content: "How are you?",
timestamp: DateTime.now().add(Duration(minutes: 10)),
),
Message(
sender: "Bob",
content: "I'm doing well, thanks!",
timestamp: DateTime.now().add(Duration(minutes: 15)),
),
// Add more messages as needed
Message(
sender: "Alice",
content: "What's your plan for the day?",
timestamp: DateTime.now().add(Duration(minutes: 20)),
),
Message(
sender: "Bob",
content: "Just working on some projects.",
timestamp: DateTime.now().add(Duration(minutes: 25)),
),
Message(
sender: "Alice",
content: "Sounds good!",
timestamp: DateTime.now().add(Duration(minutes: 30)),
),
Message(
sender: "Bob",
content: "How about you?",
timestamp: DateTime.now().add(Duration(minutes: 35)),
),
Message(
sender: "Alice",
content: "I have some errands to run.",
timestamp: DateTime.now().add(Duration(minutes: 40)),
),
Message(
sender: "Bob",
content: "Have a great day!",
timestamp: DateTime.now().add(Duration(minutes: 45)),
),
Message(
sender: "Alice",
content: "You too!",
timestamp: DateTime.now().add(Duration(minutes: 50)),
),
];
}
30 changes: 30 additions & 0 deletions frontend/lib/models/message.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
class Message {
final String? id;
final String sender;
final String content;
final DateTime? timestamp;

Message({
this.id,
required this.sender,
required this.content,
this.timestamp,
});

factory Message.fromJson(Map<String, dynamic> json) {
return Message(
id: json['_id'],
sender: json['sender'],
content: json['content'],
timestamp: DateTime.parse(json['timestamp']),
);
}

Map<String, dynamic> toJson() {
return {
'sender': sender,
'content': content,
'timestamp': timestamp!.toIso8601String(),
};
}
}
91 changes: 91 additions & 0 deletions frontend/lib/provider/chat_room_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:logger/logger.dart';
import 'package:smart_insti_app/models/message.dart';
import 'package:smart_insti_app/repositories/chat_room_repository.dart';

import '../constants/constants.dart';
import '../constants/dummy_entries.dart';

final chatRoomProvider =
StateNotifierProvider<ChatRoomStateNotifier, ChatRoomState>(
(ref) => ChatRoomStateNotifier(ref));

class ChatRoomState {
final List<Message> messageList;
final TextEditingController messageController;
final LoadingState loadingState;

ChatRoomState({
required this.messageList,
required this.messageController,
required this.loadingState,
});

ChatRoomState copyWith({
List<Message>? messageList,
TextEditingController? messageController,
LoadingState? loadingState,
}) {
return ChatRoomState(
messageList: messageList ?? this.messageList,
messageController: messageController ?? this.messageController,
loadingState: loadingState ?? this.loadingState,
);
}
}

class ChatRoomStateNotifier extends StateNotifier<ChatRoomState> {
ChatRoomStateNotifier(Ref ref)
: _api = ref.read(chatRoomRepositoryProvider),
super(
ChatRoomState(
messageList: DummyMessages.messages,
messageController: TextEditingController(),
loadingState: LoadingState.progress,
),
) {
loadMessages();
}
final ChatRoomRepository _api;
final Logger _logger = Logger();
final ScrollController scrollController = ScrollController();

void loadMessages() async {
final messages = await _api.getMessages();
state = state.copyWith(
messageList: messages,
loadingState: LoadingState.success,
);
scrollController.jumpTo(scrollController.position.maxScrollExtent);
}

void addMessage(String sender) async {
final message = Message(
sender: sender,
content: state.messageController.text,
timestamp: DateTime.now(),
);
await _api.addMessage(message);
state.messageController.clear();
loadMessages();
}

// void editMessage(int index, String newContent) {
// final messages = state.messageList;
// Message message = messages[index];
// deleteMessage(index);
// addMessage()
// }

void deleteMessage(int index) {
final messages = state.messageList;
Message message = messages[index];
_api.deleteMessage(message.id!);
messages.removeAt(index);
state = state.copyWith(messageList: messages);
for (var message in messages) {
_logger.i(message.content);
}
}
}
Loading

0 comments on commit 1e51975

Please sign in to comment.