| (customer, password)); | (customer, password)); | ||||
| } | } | ||||
| public async Task<Customer> GetCustomer(string username) | |||||
| { | |||||
| customer = await _customerManager.FindByNameAsync(username); | |||||
| return customer; | |||||
| } | |||||
| public async Task<string> GenerateToken() | public async Task<string> GenerateToken() | ||||
| { | { | ||||
| var signingCredentials = GetSigningCredentials(); | var signingCredentials = GetSigningCredentials(); |
| using Diligent.WebAPI.Data.Entities; | |||||
| using Microsoft.AspNetCore.Identity; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace Diligent.WebAPI.Business.Services | |||||
| { | |||||
| public class CustomerService : ICustomerService | |||||
| { | |||||
| private readonly UserManager<Customer> _customerManager; | |||||
| public CustomerService(UserManager<Customer> customerManager) | |||||
| { | |||||
| _customerManager = customerManager; | |||||
| } | |||||
| public async Task<Customer> GetCustomer(string username) | |||||
| { | |||||
| var customer = await _customerManager.FindByNameAsync(username); | |||||
| return customer; | |||||
| } | |||||
| public async Task<Customer> GetCustomerById(string id) | |||||
| { | |||||
| var customer = await _customerManager.FindByIdAsync(id); | |||||
| return customer; | |||||
| } | |||||
| public async Task<bool> AddNotification(string receiverId, string roomId) | |||||
| { | |||||
| var receiver = await GetCustomerById(receiverId); | |||||
| if (receiver == null) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| var notificationExists = receiver.Notifications.Where(x => x.RoomId == roomId).FirstOrDefault(); | |||||
| if (notificationExists == null) | |||||
| { | |||||
| var notification = new Notification | |||||
| { | |||||
| Count = 1, | |||||
| RoomId = roomId | |||||
| }; | |||||
| receiver.Notifications.Add(notification); | |||||
| } | |||||
| else | |||||
| { | |||||
| notificationExists.Count++; | |||||
| } | |||||
| await _customerManager.UpdateAsync(receiver); | |||||
| return true; | |||||
| } | |||||
| public async Task<List<Notification>> ReadNotifications(string userId) | |||||
| { | |||||
| var user = await _customerManager.FindByIdAsync(userId); | |||||
| return user.Notifications; | |||||
| } | |||||
| public async Task<bool> DeleteNotification(string userId, string roomId) | |||||
| { | |||||
| var user = await GetCustomerById(userId); | |||||
| if (user == null) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| var notification = user.Notifications.Where(x => x.RoomId == roomId).FirstOrDefault(); | |||||
| if (notification == null) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| user.Notifications.Remove(notification); | |||||
| await _customerManager.UpdateAsync(user); | |||||
| return true; | |||||
| } | |||||
| } | |||||
| } |
| public interface IAuthenticationService | public interface IAuthenticationService | ||||
| { | { | ||||
| Task<bool> ValidateCustomer(string usernmae,string password); | Task<bool> ValidateCustomer(string usernmae,string password); | ||||
| Task<Customer> GetCustomer(string username); | |||||
| Task<string> GenerateToken(); | Task<string> GenerateToken(); | ||||
| } | } | ||||
| } | } |
| using Diligent.WebAPI.Data.Entities; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace Diligent.WebAPI.Business.Services | |||||
| { | |||||
| public interface ICustomerService | |||||
| { | |||||
| Task<Customer> GetCustomer(string username); | |||||
| Task<Customer> GetCustomerById(string id); | |||||
| Task<bool> AddNotification(string receiverId, string roomId); | |||||
| Task<List<Notification>> ReadNotifications(string userId); | |||||
| Task<bool> DeleteNotification(string userId, string roomId); | |||||
| } | |||||
| } |
| { | { | ||||
| public string FirstName { get; set; } | public string FirstName { get; set; } | ||||
| public string LastName { get; set; } | public string LastName { get; set; } | ||||
| public List<Notification> Notifications { get; set; } = new(); | |||||
| } | } | ||||
| } | } |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace Diligent.WebAPI.Data.Entities | |||||
| { | |||||
| public class Notification : BaseMongo | |||||
| { | |||||
| public string RoomId { get; set; } | |||||
| public int Count { get; set; } | |||||
| } | |||||
| } |
| private readonly RoleManager<Roles> _roleManager; | private readonly RoleManager<Roles> _roleManager; | ||||
| private readonly IAuthenticationService _authenticationService; | private readonly IAuthenticationService _authenticationService; | ||||
| private readonly IMapper _mapper; | private readonly IMapper _mapper; | ||||
| private readonly ICustomerService _customerService; | |||||
| public CustomerController(UserManager<Customer> customerManager, RoleManager<Roles> roleManager,IAuthenticationService authenticationService, | |||||
| IMapper mapper) | |||||
| public CustomerController(UserManager<Customer> customerManager, RoleManager<Roles> roleManager, IAuthenticationService authenticationService, | |||||
| IMapper mapper, ICustomerService customerService) | |||||
| { | { | ||||
| _customerManager = customerManager; | _customerManager = customerManager; | ||||
| _roleManager = roleManager; | _roleManager = roleManager; | ||||
| _authenticationService = authenticationService; | _authenticationService = authenticationService; | ||||
| _mapper = mapper; | _mapper = mapper; | ||||
| _customerService = customerService; | |||||
| } | } | ||||
| [HttpPost("login")] | [HttpPost("login")] | ||||
| public async Task<ActionResult<CustomerReadDTO>> Login(CustomerLoginDTO customerLoginDTO) | public async Task<ActionResult<CustomerReadDTO>> Login(CustomerLoginDTO customerLoginDTO) | ||||
| if (!await _authenticationService.ValidateCustomer(customerLoginDTO.Username, customerLoginDTO.Password)) | if (!await _authenticationService.ValidateCustomer(customerLoginDTO.Username, customerLoginDTO.Password)) | ||||
| return BadRequest("Authentication failed.Wrong Username or password"); | return BadRequest("Authentication failed.Wrong Username or password"); | ||||
| Customer customer = await _authenticationService.GetCustomer(customerLoginDTO.Username); | |||||
| Customer customer = await _customerService.GetCustomer(customerLoginDTO.Username); | |||||
| var customerReadDTO = _mapper.Map<CustomerReadDTO>(customer); | var customerReadDTO = _mapper.Map<CustomerReadDTO>(customer); | ||||
| customerReadDTO.Token = await _authenticationService.GenerateToken(); | customerReadDTO.Token = await _authenticationService.GenerateToken(); | ||||
| customerReadDTO.Roles = (List<string>)await _customerManager.GetRolesAsync(customer); | customerReadDTO.Roles = (List<string>)await _customerManager.GetRolesAsync(customer); |
| using Diligent.WebAPI.Host.Mediator.Notifications.Queries; | |||||
| using MediatR; | |||||
| using Microsoft.AspNetCore.Mvc; | |||||
| namespace Diligent.WebAPI.Host.Controllers | |||||
| { | |||||
| [ApiVersion("1.0")] | |||||
| [ApiController] | |||||
| [Route("v{version:apiVersion}/[controller]")] | |||||
| public class NotificationController : ControllerBase | |||||
| { | |||||
| private readonly IMediator _mediator; | |||||
| public NotificationController(IMediator mediator) | |||||
| { | |||||
| _mediator = mediator; | |||||
| } | |||||
| [HttpGet("{id}")] | |||||
| public async Task<IActionResult> GetNotifications([FromRoute] string id) => | |||||
| Ok(await _mediator.Send(new GetNotificationsQuery(id))); | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.DTOs.Notification | |||||
| { | |||||
| public class NotificationDeleteDTO | |||||
| { | |||||
| public string UserId { get; set; } | |||||
| public string RoomId { get; set; } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.DTOs.Notification | |||||
| { | |||||
| public class NotificationReadDTO | |||||
| { | |||||
| public string RoomId { get; set; } | |||||
| public int Count { get; set; } | |||||
| } | |||||
| } |
| namespace Diligent.WebAPI.Host.DTOs.Notification | |||||
| { | |||||
| public class NotificationSaveDTO | |||||
| { | |||||
| public string ReceiverId { get; set; } | |||||
| public string RoomId { get; set; } | |||||
| } | |||||
| } |
| builder.Services.AddAutoMapper(typeof(PolicyMappingProfiles)); | builder.Services.AddAutoMapper(typeof(PolicyMappingProfiles)); | ||||
| builder.Services.AddAutoMapper(typeof(RequestMappingProfile)); | builder.Services.AddAutoMapper(typeof(RequestMappingProfile)); | ||||
| builder.Services.AddScoped<IAuthenticationService, AuthenticationService>(); | builder.Services.AddScoped<IAuthenticationService, AuthenticationService>(); | ||||
| //builder.Services.AddScoped<IInsuranceCompanyService, InsuranceCompanyService>(); | //builder.Services.AddScoped<IInsuranceCompanyService, InsuranceCompanyService>(); | ||||
| // mongo service life cycle | // mongo service life cycle | ||||
| builder.Services.AddScoped<ICustomerService, CustomerService>(); | |||||
| builder.Services.AddSingleton<InsuranceCompanyService>(); | builder.Services.AddSingleton<InsuranceCompanyService>(); | ||||
| builder.Services.AddSingleton<InsurancePolicyService>(); | builder.Services.AddSingleton<InsurancePolicyService>(); | ||||
| builder.Services.AddSingleton<InsurerService>(); | builder.Services.AddSingleton<InsurerService>(); |
| using Diligent.WebAPI.Data.Entities; | using Diligent.WebAPI.Data.Entities; | ||||
| using Diligent.WebAPI.Host.DTOs.Notification; | |||||
| using Diligent.WebAPI.Host.Mediator.Messages.Commands; | using Diligent.WebAPI.Host.Mediator.Messages.Commands; | ||||
| using Diligent.WebAPI.Host.Mediator.Notifications.Commands; | |||||
| using MediatR; | using MediatR; | ||||
| using Microsoft.AspNetCore.Authorization; | using Microsoft.AspNetCore.Authorization; | ||||
| using Microsoft.AspNetCore.SignalR; | using Microsoft.AspNetCore.SignalR; | ||||
| // return base.OnDisconnectedAsync(exception); | // return base.OnDisconnectedAsync(exception); | ||||
| //} | //} | ||||
| // Not completed | |||||
| //[HubMethodName("SendMessageToUser")] | |||||
| //public async Task DirectMessage(string message) | |||||
| //{ | |||||
| // // Send message to another user | |||||
| // await Clients.User(message.User).ReceiveMessage(new ChatMessage { User = "Ermin", Message = message.Message }); | |||||
| //} | |||||
| [HubMethodName("SendMessageToGroup")] | [HubMethodName("SendMessageToGroup")] | ||||
| public async Task SendMessageToGroup(ChatMessage message) | public async Task SendMessageToGroup(ChatMessage message) | ||||
| { | { | ||||
| // Find user's room and send message to everyone | // Find user's room and send message to everyone | ||||
| //if (_connections.TryGetValue(Context.ConnectionId, out UserConnection room)) | |||||
| // All other users will receive notification | |||||
| if (_connections.TryGetValue(message.ConnId, out UserConnection room)) | if (_connections.TryGetValue(message.ConnId, out UserConnection room)) | ||||
| { | { | ||||
| await Clients.Group(room.RoomId).ReceiveMessage(new ChatMessage { User = room.UserId, Message = message.Message }); | await Clients.Group(room.RoomId).ReceiveMessage(new ChatMessage { User = room.UserId, Message = message.Message }); | ||||
| await _mediator.Send(new AddMessageCommand(room.RoomId, new Message {Content=message.Message,SenderId=message.UserId,Username=room.Username })); | |||||
| await Clients.OthersInGroup(room.RoomId).ReceiveNotifications(room.UserId, room.RoomId); | |||||
| await _mediator.Send(new AddMessageCommand(room.RoomId, new Message { Content = message.Message, SenderId = message.UserId, Username = room.Username })); | |||||
| // Find other users in room and save notification in database | |||||
| foreach (KeyValuePair<string, UserConnection> conn in _connections) | |||||
| { | |||||
| if (conn.Value.RoomId == room.RoomId && conn.Key != message.ConnId) | |||||
| { | |||||
| await _mediator.Send(new AddNotificationCommand(new NotificationSaveDTO { RoomId = room.RoomId, ReceiverId = conn.Value.UserId })); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| // If user is not in room, add him | // If user is not in room, add him | ||||
| // Return message "User has joined room" to all users in room | // Return message "User has joined room" to all users in room | ||||
| if(result.Value == null) | |||||
| if (result.Value == null) | |||||
| { | { | ||||
| await Groups.AddToGroupAsync(Context.ConnectionId, userConnection.RoomId); | await Groups.AddToGroupAsync(Context.ConnectionId, userConnection.RoomId); | ||||
| _connections[Context.ConnectionId] = userConnection; | _connections[Context.ConnectionId] = userConnection; | ||||
| await Clients.Group(userConnection.RoomId).ReceiveMessage(new ChatMessage { User = userConnection.UserId, Message = $"{userConnection.Username} has joined room", ConnId = Context.ConnectionId }); | await Clients.Group(userConnection.RoomId).ReceiveMessage(new ChatMessage { User = userConnection.UserId, Message = $"{userConnection.Username} has joined room", ConnId = Context.ConnectionId }); | ||||
| } | } | ||||
| else | |||||
| { | |||||
| await _mediator.Send(new DeleteNotificationCommand(new NotificationDeleteDTO { UserId = userConnection.UserId, RoomId = userConnection.RoomId })); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } |
| public interface IChatClient | public interface IChatClient | ||||
| { | { | ||||
| Task ReceiveMessage(ChatMessage message); | Task ReceiveMessage(ChatMessage message); | ||||
| Task ReceiveNotifications(string userId, string roomId); | |||||
| } | } | ||||
| } | } |
| using AutoMapper; | |||||
| using Diligent.WebAPI.Data.Entities; | |||||
| using Diligent.WebAPI.Host.DTOs.Notification; | |||||
| namespace Diligent.WebAPI.Host.Mapper | |||||
| { | |||||
| public class NotificationMappingProfile : Profile | |||||
| { | |||||
| public NotificationMappingProfile() | |||||
| { | |||||
| #region Models to DTOs | |||||
| CreateMap<Notification, NotificationReadDTO>(); | |||||
| #endregion | |||||
| } | |||||
| } | |||||
| } |
| using Diligent.WebAPI.Host.DTOs.Notification; | |||||
| using MediatR; | |||||
| namespace Diligent.WebAPI.Host.Mediator.Notifications.Commands | |||||
| { | |||||
| public class AddNotificationCommand : IRequest<Unit> | |||||
| { | |||||
| public NotificationSaveDTO Notification { get; } | |||||
| public AddNotificationCommand(NotificationSaveDTO notification) | |||||
| { | |||||
| Notification = notification; | |||||
| } | |||||
| } | |||||
| } |
| using Diligent.WebAPI.Host.DTOs.Notification; | |||||
| using MediatR; | |||||
| namespace Diligent.WebAPI.Host.Mediator.Notifications.Commands | |||||
| { | |||||
| public class DeleteNotificationCommand : IRequest<Unit> | |||||
| { | |||||
| public NotificationDeleteDTO NotificationData { get; } | |||||
| public DeleteNotificationCommand(NotificationDeleteDTO notificationData) | |||||
| { | |||||
| NotificationData = notificationData; | |||||
| } | |||||
| } | |||||
| } |
| using Diligent.WebAPI.Business.Services; | |||||
| using Diligent.WebAPI.Host.Mediator.Notifications.Commands; | |||||
| using MediatR; | |||||
| namespace Diligent.WebAPI.Host.Mediator.Notifications.Handlers | |||||
| { | |||||
| public class AddNotificationHandler : IRequestHandler<AddNotificationCommand, Unit> | |||||
| { | |||||
| private readonly ICustomerService _customerService; | |||||
| public AddNotificationHandler(ICustomerService customerService) | |||||
| { | |||||
| _customerService = customerService; | |||||
| } | |||||
| public async Task<Unit> Handle(AddNotificationCommand request, CancellationToken cancellationToken) | |||||
| { | |||||
| if (request == null) | |||||
| { | |||||
| throw new BadHttpRequestException("Object cannot be null"); | |||||
| } | |||||
| var result = await _customerService.AddNotification(request.Notification.ReceiverId, request.Notification.RoomId); | |||||
| if (!result) | |||||
| { | |||||
| throw new Exception("Problem with saving notification in database"); | |||||
| } | |||||
| return new Unit(); | |||||
| } | |||||
| } | |||||
| } |
| using Diligent.WebAPI.Business.Services; | |||||
| using Diligent.WebAPI.Host.Mediator.Notifications.Commands; | |||||
| using MediatR; | |||||
| namespace Diligent.WebAPI.Host.Mediator.Notifications.Handlers | |||||
| { | |||||
| public class DeleteNotificationHandler : IRequestHandler<DeleteNotificationCommand, Unit> | |||||
| { | |||||
| private readonly ICustomerService _customerService; | |||||
| public DeleteNotificationHandler(ICustomerService customerService) | |||||
| { | |||||
| _customerService = customerService; | |||||
| } | |||||
| public async Task<Unit> Handle(DeleteNotificationCommand request, CancellationToken cancellationToken) | |||||
| { | |||||
| if (request == null) | |||||
| { | |||||
| throw new BadHttpRequestException("Object cannot be null"); | |||||
| } | |||||
| var result = await _customerService.DeleteNotification(request.NotificationData.UserId, request.NotificationData.RoomId); | |||||
| if (!result) | |||||
| { | |||||
| throw new Exception("Problem with deleting notification"); | |||||
| } | |||||
| return new Unit(); | |||||
| } | |||||
| } | |||||
| } |
| using AutoMapper; | |||||
| using Diligent.WebAPI.Business.Services; | |||||
| using Diligent.WebAPI.Host.DTOs.Notification; | |||||
| using Diligent.WebAPI.Host.Mediator.Notifications.Queries; | |||||
| using MediatR; | |||||
| namespace Diligent.WebAPI.Host.Mediator.Notifications.Handlers | |||||
| { | |||||
| public class GetNotificationsHandler : IRequestHandler<GetNotificationsQuery, List<NotificationReadDTO>> | |||||
| { | |||||
| private readonly ICustomerService _customerService; | |||||
| private readonly IMapper _mapper; | |||||
| public GetNotificationsHandler(ICustomerService customerService, IMapper mapper) | |||||
| { | |||||
| _customerService = customerService; | |||||
| _mapper = mapper; | |||||
| } | |||||
| public async Task<List<NotificationReadDTO>> Handle(GetNotificationsQuery request, CancellationToken cancellationToken) | |||||
| { | |||||
| if (request == null) | |||||
| { | |||||
| throw new BadHttpRequestException("User id cannot be null"); | |||||
| } | |||||
| return _mapper.Map<List<NotificationReadDTO>>(await _customerService.ReadNotifications(request.UserId)); | |||||
| } | |||||
| } | |||||
| } |
| using Diligent.WebAPI.Host.DTOs.Notification; | |||||
| using MediatR; | |||||
| namespace Diligent.WebAPI.Host.Mediator.Notifications.Queries | |||||
| { | |||||
| public class GetNotificationsQuery : IRequest<List<NotificationReadDTO>> | |||||
| { | |||||
| public string UserId { get; } | |||||
| public GetNotificationsQuery(string userId) | |||||
| { | |||||
| UserId = userId; | |||||
| } | |||||
| } | |||||
| } |
| import { createJoinRequestAsync, requestActions } from "../store/request-slice"; | import { createJoinRequestAsync, requestActions } from "../store/request-slice"; | ||||
| import { fetchRequestsAsync } from "../store/request-slice"; | import { fetchRequestsAsync } from "../store/request-slice"; | ||||
| import { HubConnectionBuilder } from "@microsoft/signalr"; | import { HubConnectionBuilder } from "@microsoft/signalr"; | ||||
| import { loadNotifications } from "../store/chat-slice"; | |||||
| // Ovde ce biti dostupne grupe i razgovori | // Ovde ce biti dostupne grupe i razgovori | ||||
| const ChatList = () => { | const ChatList = () => { | ||||
| // grupe kojima je korisnik poslao zahtev za ulazak | // grupe kojima je korisnik poslao zahtev za ulazak | ||||
| const [requestedRooms, setRequestedRooms] = useState([]); | const [requestedRooms, setRequestedRooms] = useState([]); | ||||
| // chats from redux | // chats from redux | ||||
| const { rooms, status, error } = useSelector((state) => state.chat); | |||||
| const { rooms, status, error, notifications } = useSelector( | |||||
| (state) => state.chat | |||||
| ); | |||||
| const { | const { | ||||
| chosenRoom, | chosenRoom, | ||||
| status: requestsStatus, | status: requestsStatus, | ||||
| } = useSelector((state) => state.requests); | } = useSelector((state) => state.requests); | ||||
| // show modal | // show modal | ||||
| const [showModal, setShowModal] = useState(false); | const [showModal, setShowModal] = useState(false); | ||||
| const [loadedNotification, setLoadedNotification] = useState(false); | |||||
| const { user } = useContext(UserContext); | const { user } = useContext(UserContext); | ||||
| // const [connection, setConnection] = useState(); | // const [connection, setConnection] = useState(); | ||||
| // const [messages, setMessages] = useState([]); | // const [messages, setMessages] = useState([]); | ||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| useEffect(() => { | |||||
| if (user && !loadedNotification) { | |||||
| console.log("Ovde"); | |||||
| dispatch(loadNotifications(user.id)); | |||||
| setLoadedNotification((oldState) => !oldState); | |||||
| } | |||||
| }, [user, dispatch, loadedNotification]); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| dispatch(fetchChatRoomsAsync()); | dispatch(fetchChatRoomsAsync()); | ||||
| dispatch(fetchRequestsAsync()); | dispatch(fetchRequestsAsync()); | ||||
| }; | }; | ||||
| const showRoomMessagesHandler = (n) => { | const showRoomMessagesHandler = (n) => { | ||||
| dispatch(chatActions.readNotifications(n.id)); | |||||
| dispatch(chatActions.setRoom(n)); | dispatch(chatActions.setRoom(n)); | ||||
| }; | }; | ||||
| }) | }) | ||||
| ); | ); | ||||
| }); | }); | ||||
| connection.on("ReceiveNotifications", (userId, roomId) => { | |||||
| if (user.id !== userId) dispatch(chatActions.addNotification(roomId)); | |||||
| }); | |||||
| // When user changed room, array with messages from previous room will be deleted from redux | // When user changed room, array with messages from previous room will be deleted from redux | ||||
| dispatch(chatActions.newMessage({ changedRoom: true })); | dispatch(chatActions.newMessage({ changedRoom: true })); | ||||
| ); | ); | ||||
| }; | }; | ||||
| const notificationCounter = (room) => { | |||||
| for (let i = 0; i < notifications.length; i++) { | |||||
| if (notifications[i].roomId === room.id) { | |||||
| return notifications[i].notificationCount; | |||||
| } | |||||
| } | |||||
| return null; | |||||
| }; | |||||
| useEffect(() => { | useEffect(() => { | ||||
| if (requestsStatus === "idle") { | if (requestsStatus === "idle") { | ||||
| setShowModal(false); | setShowModal(false); | ||||
| key={index} | key={index} | ||||
| onClick={() => joinRoom(n)} | onClick={() => joinRoom(n)} | ||||
| > | > | ||||
| {notificationCounter(n) && ( | |||||
| <div className="h-100 d-flex align-items-center justify-content-center"> | |||||
| <span | |||||
| style={{ | |||||
| padding: "0.5rem 1rem", | |||||
| backgroundColor: "red", | |||||
| borderRadius: "50%", | |||||
| color: "white", | |||||
| }} | |||||
| > | |||||
| {notificationCounter(n)} | |||||
| </span> | |||||
| </div> | |||||
| )} | |||||
| <button | <button | ||||
| className="text-start w-100 py-3 px-3 btn btn-light h-100" | className="text-start w-100 py-3 px-3 btn btn-light h-100" | ||||
| onClick={showRoomMessagesHandler.bind(this, n)} | onClick={showRoomMessagesHandler.bind(this, n)} |
| import axios from "axios"; | |||||
| import { apiUrl } from "../config/urls"; | |||||
| axios.defaults.baseURL = apiUrl; | |||||
| const responseBody = (response) => response.data; | |||||
| const methods = { | |||||
| loadNotifications: (userId) => | |||||
| axios.get(`/Notification/${userId}`).then(responseBody), | |||||
| }; | |||||
| export default methods; |
| import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; | import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; | ||||
| import chatService from "../services/chatService"; | import chatService from "../services/chatService"; | ||||
| import notificationService from "../services/notificationService"; | |||||
| const initialState = { | const initialState = { | ||||
| status: "idle", | status: "idle", | ||||
| messages: [], | messages: [], | ||||
| // All active user connections to rooms | // All active user connections to rooms | ||||
| connections: [], | connections: [], | ||||
| // Notifications | |||||
| notifications: [], | |||||
| }; | }; | ||||
| export const fetchChatRoomsAsync = createAsyncThunk( | export const fetchChatRoomsAsync = createAsyncThunk( | ||||
| } | } | ||||
| ); | ); | ||||
| export const loadNotifications = createAsyncThunk( | |||||
| "chat/loadNotifications", | |||||
| async (payload, thunkAPI) => { | |||||
| try { | |||||
| return await notificationService.loadNotifications(payload); | |||||
| } catch (error) { | |||||
| return thunkAPI.rejectWithValue({ error }); | |||||
| } | |||||
| } | |||||
| ); | |||||
| const chatSlice = createSlice({ | const chatSlice = createSlice({ | ||||
| name: "chat", | name: "chat", | ||||
| initialState, | initialState, | ||||
| setMessages: (state, action) => { | setMessages: (state, action) => { | ||||
| state.messages = action.payload; | state.messages = action.payload; | ||||
| }, | }, | ||||
| addNotification: (state, action) => { | |||||
| console.log(1, action.payload); | |||||
| if (state.notifications.length !== 0) { | |||||
| console.log(2); | |||||
| const room = state.notifications.find( | |||||
| (notification) => notification.roomId === action.payload | |||||
| ); | |||||
| if (room) { | |||||
| console.log(3); | |||||
| room.notificationCount++; | |||||
| } else { | |||||
| state.notifications.push({ | |||||
| roomId: action.payload, | |||||
| notificationCount: 1, | |||||
| }); | |||||
| } | |||||
| } else { | |||||
| console.log(4); | |||||
| state.notifications.push({ | |||||
| roomId: action.payload, | |||||
| notificationCount: 1, | |||||
| }); | |||||
| } | |||||
| }, | |||||
| readNotifications: (state, action) => { | |||||
| state.notifications = state.notifications.filter( | |||||
| (notification) => notification.roomId !== action.payload | |||||
| ); | |||||
| }, | |||||
| }, | }, | ||||
| extraReducers: (builder) => { | extraReducers: (builder) => { | ||||
| // Fetch chat rooms | // Fetch chat rooms | ||||
| state.status = "idle"; | state.status = "idle"; | ||||
| state.error = action.payload; | state.error = action.payload; | ||||
| }); | }); | ||||
| builder.addCase(loadNotifications.pending, (state) => { | |||||
| state.status = "pendingLoadingNotification"; | |||||
| state.error = null; | |||||
| }); | |||||
| builder.addCase(loadNotifications.fulfilled, (state, action) => { | |||||
| state.status = "idle"; | |||||
| console.log(action.payload); | |||||
| if (action.payload.length === 0) { | |||||
| state.notifications = []; | |||||
| } else { | |||||
| state.notifications = action.payload.map((n) => { | |||||
| return { roomId: n.roomId, notificationCount: n.count }; | |||||
| }); | |||||
| } | |||||
| state.error = null; | |||||
| }); | |||||
| builder.addCase(loadNotifications.rejected, (state, action) => { | |||||
| state.status = "idle"; | |||||
| state.error = action.payload; | |||||
| }); | |||||
| }, | }, | ||||
| }); | }); | ||||