瀏覽代碼

Conflicts resolved

pull/2/head
Ermin Bronja 3 年之前
父節點
當前提交
b8393d29ff

+ 23
- 0
Backend/Diligent.WebAPI.Business/Services/RoomService.cs 查看文件



public async Task<List<Room>> GetRoomsForSupport(string supportId) => public async Task<List<Room>> GetRoomsForSupport(string supportId) =>
await _mongoCollection.Find(k => k.CreatedBy == supportId).ToListAsync(); await _mongoCollection.Find(k => k.CreatedBy == supportId).ToListAsync();

public async Task<bool> LeaveChatRoom(string roomId, string userId)
{
var room = await GetRoomAsync(roomId);

if (room == null)
{
return false;
}

var userConnection = room.Customers.Where(x => x.CustomerId == userId).FirstOrDefault();

if (userConnection == null)
{
return false;
}

room.Customers.Remove(userConnection);

await _mongoCollection.ReplaceOneAsync(x => x.Id == roomId, room);

return true;
}
} }
} }

+ 1
- 1
Backend/Diligent.WebAPI.Host/Controllers/CustomerController.cs 查看文件

}; };


var result = await _customerManager.CreateAsync(customer, customerCreateDTO.Password); var result = await _customerManager.CreateAsync(customer, customerCreateDTO.Password);
await _customerManager.AddToRoleAsync(customer, "Customer");
await _customerManager.AddToRoleAsync(customer, "Support");


if (!result.Succeeded) if (!result.Succeeded)
{ {

+ 7
- 0
Backend/Diligent.WebAPI.Host/DTOs/Chat/LeaveChatRoomDTO.cs 查看文件

namespace Diligent.WebAPI.Host.DTOs.Chat
{
public class LeaveChatRoomDTO
{
public string ConnId { get; set; }
}
}

+ 13
- 0
Backend/Diligent.WebAPI.Host/Hubs/ChatHub.cs 查看文件

using Diligent.WebAPI.Data.Entities; using Diligent.WebAPI.Data.Entities;
using Diligent.WebAPI.Host.DTOs.Notification; using Diligent.WebAPI.Host.DTOs.Notification;
using Diligent.WebAPI.Host.DTOs.Chat;
using Diligent.WebAPI.Host.Mediator.Chat.Commands;
using Diligent.WebAPI.Host.Mediator.Messages.Commands; using Diligent.WebAPI.Host.Mediator.Messages.Commands;
using Diligent.WebAPI.Host.Mediator.Notifications.Commands; using Diligent.WebAPI.Host.Mediator.Notifications.Commands;
using MediatR; using MediatR;
await _mediator.Send(new DeleteNotificationCommand(new NotificationDeleteDTO { UserId = userConnection.UserId, RoomId = userConnection.RoomId })); await _mediator.Send(new DeleteNotificationCommand(new NotificationDeleteDTO { UserId = userConnection.UserId, RoomId = userConnection.RoomId }));
} }
} }

[HubMethodName("LeaveRoom")]
public async Task LeaveRoom(LeaveChatRoomDTO connection)
{
if (_connections.TryGetValue(connection.ConnId, out UserConnection room))
{
_connections.Remove(Context.ConnectionId);
await Clients.OthersInGroup(room.RoomId).ReceiveMessage(new ChatMessage { User = room.UserId, Message = $"{room.Username} has left room" });
await _mediator.Send(new RemoveUserFromGroupCommand(room.RoomId, room.UserId));
}
}
} }
} }

+ 16
- 0
Backend/Diligent.WebAPI.Host/Mediator/Chat/Commands/RemoveUserFromGroupCommand.cs 查看文件

using MediatR;

namespace Diligent.WebAPI.Host.Mediator.Chat.Commands
{
public class RemoveUserFromGroupCommand : IRequest<Unit>
{
public string RoomId { get; }
public string UserId { get; }

public RemoveUserFromGroupCommand(string roomId, string userId)
{
RoomId = roomId;
UserId = userId;
}
}
}

+ 33
- 0
Backend/Diligent.WebAPI.Host/Mediator/Chat/Handlers/RemoveUserFromGroupHandler.cs 查看文件

using Diligent.WebAPI.Business.Services;
using Diligent.WebAPI.Host.Mediator.Chat.Commands;
using MediatR;

namespace Diligent.WebAPI.Host.Mediator.Chat.Handlers
{
public class RemoveUserFromGroupHandler : IRequestHandler<RemoveUserFromGroupCommand, Unit>
{
private readonly RoomService _roomService;

public RemoveUserFromGroupHandler(RoomService roomService)
{
_roomService = roomService;
}

public async Task<Unit> Handle(RemoveUserFromGroupCommand request, CancellationToken cancellationToken)
{
if (request == null)
{
throw new BadHttpRequestException("Object cannot be null");
}

var result = await _roomService.LeaveChatRoom(request.RoomId, request.UserId);

if (!result)
{
throw new Exception("Problem with deleting user from group");
}

return new Unit();
}
}
}

+ 57
- 26
Frontend/src/components/ChatWindow.js 查看文件

import { chatActions } from "../store/chat-slice"; import { chatActions } from "../store/chat-slice";


const ChatWindow = ({ room }) => { const ChatWindow = ({ room }) => {
const messagesEndRef = useRef(null)
const messagesEndRef = useRef(null);


const scrollToBottom = () => { const scrollToBottom = () => {
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" })
}
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
};


const [message, setMessage] = useState(""); const [message, setMessage] = useState("");
const { user } = useContext(UserContext); const { user } = useContext(UserContext);
dispatch(chatActions.setMessages(room.messages)); dispatch(chatActions.setMessages(room.messages));
}, [dispatch, room.messages]); }, [dispatch, room.messages]);


useEffect(()=>{
useEffect(() => {
scrollToBottom(); scrollToBottom();
},[])
}, []);

const leftRoomHandler = async () => {
const userToFetch = connections.filter(
(conn) => conn.userId === user.id && conn.roomId === activeRoom.id
);

console.log(userToFetch[0].connId, user.id, activeRoom.id);

await connection.invoke("LeaveRoom", {
connId: userToFetch[0].connId,
});
dispatch(
chatActions.leaveRoom({ roomId: activeRoom.id, customerId: user.id })
);
};


const onSendMessageToGroupHandler = async () => { const onSendMessageToGroupHandler = async () => {
const userToFetch = connections.filter( const userToFetch = connections.filter(
connId: userToFetch[0].connId, connId: userToFetch[0].connId,
}); });


setMessage('')
setMessage("");
}; };


return ( return (
<div className="px-3 bg-light-transparent rounded h-100 d-flex flex-column"> <div className="px-3 bg-light-transparent rounded h-100 d-flex flex-column">
<div style={{ height: "80px" }}> <div style={{ height: "80px" }}>
<h2 className="py-3 m-0">{room.name}</h2>
<h2 className="py-1 m-0">{room.name}</h2>
<button
onClick={leftRoomHandler}
style={{
border: 0,
backgroundColor: "transparent",
padding: 0,
margin: 0,
textDecoration: "underline",
}}
>
Leave Room
</button>
</div> </div>


<div className="messages p-3 border d-flex flex-column-reverse"> <div className="messages p-3 border d-flex flex-column-reverse">
{/* mapirane poruke */} {/* mapirane poruke */}


{messages.map((n, index) => (
<div
key={index}
className={
n.senderId === user.id
? "d-flex flex-column align-items-end"
: "d-flex flex-column align-items-start"
}
>
<p
className={`p-2 px-4 mb-0 rounded message ${
n.senderId !== user.id ? "bg-primary text-light" : "bg-light text-dark"
}`}
{messages
.map((n, index) => (
<div
key={index}
className={
n.senderId === user.id
? "d-flex flex-column align-items-end"
: "d-flex flex-column align-items-start"
}
> >
{/* {n.message} */}
{n.content}
</p>
<p className="text-muted small m-0 p-0 mb-4">{n.username}</p>
</div>
)).reverse()}
<p
className={`p-2 px-4 mb-0 rounded message ${
n.senderId !== user.id
? "bg-primary text-light"
: "bg-light text-dark"
}`}
>
{/* {n.message} */}
{n.content}
</p>
<p className="text-muted small m-0 p-0 mb-4">{n.username}</p>
</div>
))
.reverse()}
<div ref={messagesEndRef} /> <div ref={messagesEndRef} />
</div> </div>



+ 12
- 0
Frontend/src/store/chat-slice.js 查看文件

(notification) => notification.roomId !== action.payload (notification) => notification.roomId !== action.payload
); );
}, },
},
leaveRoom: (state, action) => {
state.activeRoom = null;

const room = state.rooms.find(
(room) => room.id === action.payload.roomId
);

room.customers = room.customers.filter(
(customer) => customer.customerId !== action.payload.customerId
);
},
}, },
extraReducers: (builder) => { extraReducers: (builder) => {
// Fetch chat rooms // Fetch chat rooms

Loading…
取消
儲存