UNPKG

@selfcommunity/react-core

Version:

React Core Components useful for integrating UI Community components (react-ui).

115 lines (114 loc) 5.55 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const react_1 = require("react"); const types_1 = require("@selfcommunity/types"); const SCContextProvider_1 = require("../components/provider/SCContextProvider"); const SCUserProvider_1 = require("../components/provider/SCUserProvider"); const utils_1 = require("@selfcommunity/utils"); const Notification_1 = require("../constants/Notification"); const WebSocket_1 = require("../constants/WebSocket"); const pubsub_js_1 = tslib_1.__importDefault(require("pubsub-js")); /** :::info This custom hook is used to init web socket. ::: */ function useSCWebSocket() { const scContext = (0, SCContextProvider_1.useSCContext)(); const scUserContext = (0, SCUserProvider_1.useSCUser)(); const [wsInstance, setWsInstance] = (0, react_1.useState)(null); // Websocket uri, prefixPath, protocols and sub-protocols const _wsProtocol = scContext.settings.notifications.webSocket.secure || !('secure' in scContext.settings.notifications.webSocket) ? WebSocket_1.WS_PROTOCOL_SECURE : WebSocket_1.WS_PROTOCOL_INSECURE; const _wsPrefixPath = scContext.settings.notifications.webSocket.prefixPath || WebSocket_1.WS_PREFIX_PATH; const _wsUri = `${_wsProtocol}://${new URL(scContext.settings.portal).hostname}/${_wsPrefixPath}/${WebSocket_1.WS_FACILITY_NOTIFY}?subscribe-user`; const _wsSubProtocol = scContext.settings.session.authToken && scContext.settings.session.authToken.accessToken ? `${WebSocket_1.WS_SUB_PROTOCOL_PREFIX}${scContext.settings.session.authToken.accessToken}` : null; /** * Before document unload handler * Close webSocket */ const handleBeforeUnload = () => { wsInstance && wsInstance.close(); }; /** * Check if there is a currently active session and a * wsInstance connection when the provider is mounted for the first time. * If there is an error, it means there is no session. */ (0, react_1.useEffect)(() => { if (scUserContext.user && !wsInstance && _wsUri && _wsSubProtocol) { setWsInstance(utils_1.WSClient.getInstance({ uri: _wsUri, heartbeatMsg: WebSocket_1.WS_HEARTBEAT_MESSAGE, protocols: [_wsSubProtocol], receiveMessage: receiveMessage, })); // Close the socket channel before window unload window.addEventListener('beforeunload', handleBeforeUnload); } if (!scUserContext.user && wsInstance) { // Disconnect the socket window.removeEventListener('beforeunload', handleBeforeUnload); wsInstance && wsInstance.close(); } }, [scUserContext.user]); /** * Receive a message from wsInstance. */ const receiveMessage = (data) => { // receive a message though the websocket from the server let _data = JSON.parse(data); if (_data && _data.type && Notification_1.SCNotificationTopics.includes(_data.type)) { if (_data.type === types_1.SCNotificationTopicType.INTERACTION) { /** * With topic interaction there are two types of notifications group: * - notification_banner * - comment, nested_comment, follow, etc.. */ if (_data.data.activity_type === types_1.SCNotificationTypologyType.NOTIFICATION_BANNER) { /** * Notification of type 'notification_banner' * It is a special case of notifications with topic 'interaction' */ pubsub_js_1.default.publish(`${_data.type}.${types_1.SCNotificationTypologyType.NOTIFICATION_BANNER}`, _data); } else if (Notification_1.SCNotificationMapping[_data.data.activity_type]) { /** * Notification of type 'comment', 'nested_comment', etc... */ pubsub_js_1.default.publish(`${_data.type}.${Notification_1.SCNotificationMapping[_data.data.activity_type]}`, _data); } setNotificationCounters(_data.data); } else { pubsub_js_1.default.publish(`${_data.type}`, _data); } } }; /** * Update user context counters * @param payload */ const setNotificationCounters = (payload) => { /** * The counter count_interactions includes pure interactions and notification banners, * so unseen_interactions_counter = payload.count_interactions - payload.count_notification_banners * if payload.count_notification_banners exists (was added later in the payload of the message ws) */ let unseen_interactions_counter = 0; if (payload.count_interactions !== undefined) { unseen_interactions_counter = payload.count_interactions; } if (payload.count_notification_banners !== undefined) { unseen_interactions_counter = Math.max(unseen_interactions_counter - payload.count_notification_banners, 0); scUserContext.setUnseenInteractionsCounter(payload.count_notification_banners); } payload.count_interactions !== undefined && scUserContext.setUnseenInteractionsCounter(unseen_interactions_counter); }; return { wsInstance, setWsInstance }; } exports.default = useSCWebSocket;