Skip to content

Commit

Permalink
feat: add initial handling for simultaneous login websocket
Browse files Browse the repository at this point in the history
  • Loading branch information
naumovski-filip committed Jun 1, 2023
1 parent 906f2e9 commit b28d0a2
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 32 deletions.
13 changes: 12 additions & 1 deletion src/components/Root/Root.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FC, useEffect, useMemo } from 'react';
import React, { FC, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useQuery } from 'react-query';
import { useSearchParams } from 'react-router-dom';
Expand All @@ -14,6 +14,8 @@ import { loadAndValidateConfig } from '#src/utils/configLoad';
import { initSettings } from '#src/stores/SettingsController';
import AppRoutes from '#src/containers/AppRoutes/AppRoutes';
import registerCustomScreens from '#src/screenMapping';
import { useAccountStore } from '#src/stores/AccountStore';
import { subscribeToNotifications } from '#src/stores/NotificationsController';

const Root: FC = () => {
const { t } = useTranslation('error');
Expand Down Expand Up @@ -45,6 +47,15 @@ const Root: FC = () => {
registerCustomScreens();
}, []);

const user = useAccountStore((state) => state.user);
const [isSubscribed, setIsSubscribed] = useState(false);
useEffect(() => {
if (!isSubscribed && user?.id && user?.uuid) {
subscribeToNotifications(user.uuid);
setIsSubscribed(true);
}
}, [user?.id, user?.uuid, isSubscribed]);

const IS_DEMO_OR_PREVIEW = IS_DEMO_MODE || IS_PREVIEW_MODE;

// Show the spinner while loading except in demo mode (the demo config shows its own loading status)
Expand Down
4 changes: 2 additions & 2 deletions src/services/inplayer.account.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ export const register: Register = async ({ config, email, password }) => {

export const logout = async () => {
try {
await InPlayer.Account.signOut();
return InPlayer.Notifications.unsubscribe();
InPlayer.Notifications.unsubscribe();
InPlayer.Account.signOut();
} catch {
throw new Error('Failed to sign out.');
}
Expand Down
22 changes: 17 additions & 5 deletions src/stores/AccountController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,24 @@ export const refreshJwtToken = async (auth: AuthData) => {

export const getAccount = async (auth: AuthData) => {
await useService(async ({ accountService, config, accessModel }) => {
const response = await accountService.getUser({ config, auth });
if (response) {
await afterLogin(auth, response.user, response.customerConsents, accessModel);
}
try {
const response = await accountService.getUser({ config, auth });
if (response) {
await afterLogin(auth, response.user, response.customerConsents, accessModel);
}

useAccountStore.setState({ loading: false });
useAccountStore.setState({ loading: false });
} catch (error: unknown) {
useAccountStore.setState({
auth: null,
user: null,
subscription: null,
transactions: null,
activePayment: null,
customerConsents: null,
publisherConsents: null,
});
}
});
};

Expand Down
55 changes: 31 additions & 24 deletions src/stores/NotificationsController.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { reloadActiveSubscription } from './AccountController';
import { getAccount, reloadActiveSubscription } from './AccountController';

import useService from '#src/hooks/useService';
import { addQueryParams } from '#src/utils/formatting';
import useAccount from '#src/hooks/useAccount';

export enum NotificationsTypes {
ACCESS_GRANTED = 'access.granted',
Expand All @@ -14,30 +15,36 @@ export enum NotificationsTypes {
}

export const subscribeToNotifications = async (uuid: string = '') => {
return await useService(async ({ accountService }) => {
return await accountService.subscribeToNotifications(uuid, async (message) => {
if (message) {
const notification = JSON.parse(message);
switch (notification.type) {
case NotificationsTypes.FAILED:
case NotificationsTypes.SUBSCRIBE_FAILED:
window.location.href = addQueryParams(window.location.href, { u: 'payment-error', message: notification.resource?.message });
break;
case NotificationsTypes.ACCESS_GRANTED:
await reloadActiveSubscription();
window.location.href = addQueryParams(window.location.href, { u: 'welcome' });
break;
case NotificationsTypes.ACCESS_REVOKED:
await reloadActiveSubscription();
break;
case NotificationsTypes.CARD_REQUIRES_ACTION:
case NotificationsTypes.SUBSCRIBE_REQUIRES_ACTION:
window.location.href = notification.resource?.redirect_to_url;
break;
default:
break;
return await useAccount(async ({ auth }) => {
return await useService(async ({ accountService }) => {
return await accountService.subscribeToNotifications(uuid, async (message) => {
if (message) {
const notification = JSON.parse(message);
switch (notification.type) {
case NotificationsTypes.FAILED:
case NotificationsTypes.SUBSCRIBE_FAILED:
window.location.href = addQueryParams(window.location.href, { u: 'payment-error', message: notification.resource?.message });
break;
case NotificationsTypes.ACCOUNT_LOGOUT:
await getAccount(auth);
// redirect to login page with message
break;
case NotificationsTypes.ACCESS_GRANTED:
await reloadActiveSubscription();
window.location.href = addQueryParams(window.location.href, { u: 'welcome' });
break;
case NotificationsTypes.ACCESS_REVOKED:
await reloadActiveSubscription();
break;
case NotificationsTypes.CARD_REQUIRES_ACTION:
case NotificationsTypes.SUBSCRIBE_REQUIRES_ACTION:
window.location.href = notification.resource?.redirect_to_url;
break;
default:
break;
}
}
}
});
});
});
};

0 comments on commit b28d0a2

Please sign in to comment.