- added websocket;

This commit is contained in:
Vitalii Kiiko
2024-12-31 12:31:33 +01:00
3 changed files with 90 additions and 4 deletions

1
.env
View File

@@ -1,6 +1,7 @@
REACT_APP_TAB_TITLE=Gepafin REACT_APP_TAB_TITLE=Gepafin
REACT_APP_API_EXECUTION_ADDRESS=https://api-dev-gepafin.memento.credit/v1 REACT_APP_API_EXECUTION_ADDRESS=https://api-dev-gepafin.memento.credit/v1
REACT_APP_API_ADDRESS=https://api-dev-gepafin.memento.credit REACT_APP_API_ADDRESS=https://api-dev-gepafin.memento.credit
REACT_APP_API_ADDRESS_WS=https://api-dev-gepafin.memento.credit/wss
REACT_APP_LOGO_FILENAME=gepafin-logo.svg REACT_APP_LOGO_FILENAME=gepafin-logo.svg
REACT_APP_FAVICON_FILENAME=gepafin-favicon.ico REACT_APP_FAVICON_FILENAME=gepafin-favicon.ico
REACT_APP_HUB_ID=p4lk3bcx1RStqTaIVVbXs REACT_APP_HUB_ID=p4lk3bcx1RStqTaIVVbXs

View File

@@ -10,6 +10,7 @@
"@emotion/styled": "11.13.0", "@emotion/styled": "11.13.0",
"@number-flow/react": "0.4.2", "@number-flow/react": "0.4.2",
"@sentry/browser": "^8.42.0", "@sentry/browser": "^8.42.0",
"@stomp/stompjs": "^7.0.0",
"@tanstack/react-table": "^8.20.5", "@tanstack/react-table": "^8.20.5",
"@wordpress/i18n": "5.8.0", "@wordpress/i18n": "5.8.0",
"@wordpress/react-i18n": "4.8.0", "@wordpress/react-i18n": "4.8.0",
@@ -36,6 +37,7 @@
"react-hook-form": "7.53.0", "react-hook-form": "7.53.0",
"react-router-dom": "6.26.2", "react-router-dom": "6.26.2",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"sockjs-client": "^1.6.1",
"validate.js": "0.13.1", "validate.js": "0.13.1",
"zustand": "4.5.4", "zustand": "4.5.4",
"zustand-x": "3.0.4" "zustand-x": "3.0.4"

View File

@@ -1,6 +1,8 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import { __ } from '@wordpress/i18n'; import { __ } from '@wordpress/i18n';
import { head, isEmpty, pathOr } from 'ramda'; import { head, isEmpty, pathOr } from 'ramda';
import SockJS from 'sockjs-client';
import { Stomp } from '@stomp/stompjs';
// store // store
import { storeGet, useStore } from '../../store'; import { storeGet, useStore } from '../../store';
@@ -18,6 +20,8 @@ import { TabPanel, TabView } from 'primereact/tabview';
import NotificationItem from './components/NotificationItem'; import NotificationItem from './components/NotificationItem';
import NotificationItemChosen from './components/NotificationItemChosen'; import NotificationItemChosen from './components/NotificationItemChosen';
const socketUrl = process.env.REACT_APP_API_ADDRESS_WS;
const NotificationsSidebar = () => { const NotificationsSidebar = () => {
const chosenCompanyId = useStore().main.chosenCompanyId(); const chosenCompanyId = useStore().main.chosenCompanyId();
const userData = useStore().main.userData(); const userData = useStore().main.userData();
@@ -27,6 +31,10 @@ const NotificationsSidebar = () => {
const [notifications, setNotifications] = useState([]); const [notifications, setNotifications] = useState([]);
const [notificationsRead, setNotificationsRead] = useState([]); const [notificationsRead, setNotificationsRead] = useState([]);
const [chosenMsg, setChosenMsg] = useState({}); const [chosenMsg, setChosenMsg] = useState({});
const socket = useRef(null);
const stomp = useRef(null);
const [currentSubscription, setCurrentSubscription] = useState(null);
const [isConnected, setIsConnected] = useState(false);
// Handle tab change // Handle tab change
const handleTabChange = (e) => { const handleTabChange = (e) => {
@@ -61,7 +69,13 @@ const NotificationsSidebar = () => {
const userData = storeGet.main.userData(); const userData = storeGet.main.userData();
const role = pathOr('', ['role', 'roleType'], userData); const role = pathOr('', ['role', 'roleType'], userData);
if (userData.id && chosenCompanyId !== 0 && role === 'ROLE_BENEFICIARY') { if (currentSubscription) {
console.log('UNsubscribed')
currentSubscription.unsubscribe();
setCurrentSubscription(null);
}
if (isConnected && userData.id && chosenCompanyId !== 0 && role === 'ROLE_BENEFICIARY') {
setLoading(true); setLoading(true);
NotificationService.getNotifications( NotificationService.getNotifications(
userData.id, userData.id,
@@ -72,7 +86,10 @@ const NotificationsSidebar = () => {
['companyId', chosenCompanyId] ['companyId', chosenCompanyId]
] ]
); );
} else if (userData.id && role !== 'ROLE_BENEFICIARY') { if (socket.current) {
subscribeTo(`/topic/notifications_user_${userData.id}_company_${chosenCompanyId}`)
}
} else if (isConnected && userData.id && role !== 'ROLE_BENEFICIARY') {
setLoading(true); setLoading(true);
NotificationService.getNotifications( NotificationService.getNotifications(
userData.id, userData.id,
@@ -82,6 +99,9 @@ const NotificationsSidebar = () => {
['status', status] ['status', status]
] ]
); );
if (socket.current) {
subscribeTo(`/topic/notifications_user_${userData.id}`)
}
} }
} }
@@ -127,9 +147,72 @@ const NotificationsSidebar = () => {
set404FromErrorResponse(resp); set404FromErrorResponse(resp);
} }
const connectWebSocket = () => {
socket.current = new SockJS(socketUrl);
stomp.current = Stomp.over(socket.current);
stomp.current.configure({
debug: function(str) {
//console.log(str);
},
reconnectDelay: 5000,
heartbeatIncoming: 20000,
heartbeatOutgoing: 20000
});
stomp.current.connect(
{},
() => {
// connected
console.log('Websocket connected');
setIsConnected(true);
},
(error) => {
console.error('WebSocket Connection Error:', error);
setIsConnected(false);
setTimeout(connectWebSocket, 5000);
}
);
};
const subscribeTo = (topic) => {
console.log('subscribeTo', topic)
const subscription = stomp.current.subscribe(
topic,
(message) => {
try {
const notification = JSON.parse(message.body);
console.log('notification', notification)
//setNotifications(prev => [notification, ...prev]);
} catch (error) {
console.error('Error parsing notification:', error);
}
}
);
setCurrentSubscription(subscription);
}
useEffect(() => { useEffect(() => {
fetchMessages(); fetchMessages();
}, [chosenCompanyId, userData.id]); }, [chosenCompanyId, userData.id, isConnected]);
useEffect(() => {
connectWebSocket();
return () => {
if (currentSubscription) {
currentSubscription.unsubscribe();
setCurrentSubscription(null);
}
if (stomp.current) {
stomp.current.disconnect(() => {
console.log('WebSocket Disconnected');
});
}
};
}, []);
return ( return (
<> <>