@selfcommunity/react-core
Version:
React Core Components useful for integrating UI Community components (react-ui).
115 lines (114 loc) • 5.55 kB
JavaScript
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;
;