2022-05-30 15:40:11 +04:00

222 lines
5.4 KiB
TypeScript

import {
addActionHandler, getActions, getGlobal, setGlobal,
} from '../../index';
import type { GlobalState } from '../../types';
import type {
ApiUpdateAuthorizationState,
ApiUpdateAuthorizationError,
ApiUpdateConnectionState,
ApiUpdateSession,
ApiUpdateCurrentUser, ApiUpdateServerTimeOffset,
} from '../../../api/types';
import { DEBUG, SESSION_USER_KEY } from '../../../config';
import { subscribe } from '../../../util/notifications';
import { updateUser } from '../../reducers';
import { setLanguage } from '../../../util/langProvider';
import { selectNotifySettings } from '../../selectors';
import { forceWebsync } from '../../../util/websync';
import { getShippingError } from '../../../util/getReadableErrorText';
addActionHandler('apiUpdate', (global, actions, update) => {
if (DEBUG) {
if (update['@type'] !== 'updateUserStatus' && update['@type'] !== 'updateServerTimeOffset') {
// eslint-disable-next-line no-console
console.log('[GramJs] UPDATE', update['@type'], { update });
}
}
switch (update['@type']) {
case 'updateApiReady':
onUpdateApiReady(global);
break;
case 'updateAuthorizationState':
onUpdateAuthorizationState(update);
break;
case 'updateAuthorizationError':
onUpdateAuthorizationError(update);
break;
case 'updateConnectionState':
onUpdateConnectionState(update);
break;
case 'updateSession':
onUpdateSession(update);
break;
case 'updateServerTimeOffset':
onUpdateServerTimeOffset(update);
break;
case 'updateCurrentUser':
onUpdateCurrentUser(update);
break;
case 'error': {
if (update.error.message === 'SESSION_REVOKED') {
actions.signOut();
}
const paymentShippingError = getShippingError(update.error);
if (paymentShippingError) {
actions.addPaymentError({ error: paymentShippingError });
} else if (actions.showDialog) {
actions.showDialog({ data: update.error });
}
break;
}
}
});
function onUpdateApiReady(global: GlobalState) {
const { hasWebNotifications, hasPushNotifications } = selectNotifySettings(global);
if (hasWebNotifications && hasPushNotifications) {
void subscribe();
}
void setLanguage(global.settings.byKey.language);
}
function onUpdateAuthorizationState(update: ApiUpdateAuthorizationState) {
let global = getGlobal();
const wasAuthReady = global.authState === 'authorizationStateReady';
const authState = update.authorizationState;
setGlobal({
...global,
authState,
authIsLoading: false,
});
global = getGlobal();
switch (authState) {
case 'authorizationStateLoggingOut':
void forceWebsync(false);
setGlobal({
...global,
isLoggingOut: true,
});
break;
case 'authorizationStateWaitCode':
setGlobal({
...global,
authIsCodeViaApp: update.isCodeViaApp,
});
break;
case 'authorizationStateWaitPassword':
setGlobal({
...global,
authHint: update.hint,
});
break;
case 'authorizationStateWaitQrCode':
setGlobal({
...global,
authIsLoadingQrCode: false,
authQrCode: update.qrCode,
});
break;
case 'authorizationStateReady': {
if (wasAuthReady) {
break;
}
void forceWebsync(true);
setGlobal({
...global,
isLoggingOut: false,
});
break;
}
}
}
function onUpdateAuthorizationError(update: ApiUpdateAuthorizationError) {
setGlobal({
...getGlobal(),
authError: update.message,
});
}
function onUpdateConnectionState(update: ApiUpdateConnectionState) {
const { connectionState } = update;
const global = getGlobal();
if (connectionState === global.connectionState) {
return;
}
setGlobal({
...global,
connectionState,
});
if (connectionState === 'connectionStateBroken') {
// When mounting Auth `initApi` will be called from an effect. Otherwise, we force it here.
const isOnAuth = !global.authState || [
'authorizationStateWaitPhoneNumber',
'authorizationStateWaitCode',
'authorizationStateWaitPassword',
'authorizationStateWaitRegistration',
'authorizationStateWaitQrCode',
].includes(global.authState);
getActions().signOut({ forceInitApi: isOnAuth });
}
}
function onUpdateSession(update: ApiUpdateSession) {
const { sessionData } = update;
const { authRememberMe, authState } = getGlobal();
const isEmpty = !sessionData || !sessionData.mainDcId;
if (!authRememberMe || authState !== 'authorizationStateReady' || isEmpty) {
return;
}
getActions().saveSession({ sessionData });
}
function onUpdateServerTimeOffset(update: ApiUpdateServerTimeOffset) {
const global = getGlobal();
if (global.serverTimeOffset === update.serverTimeOffset) {
return;
}
setGlobal({
...global,
serverTimeOffset: update.serverTimeOffset,
});
}
function onUpdateCurrentUser(update: ApiUpdateCurrentUser) {
const { currentUser } = update;
setGlobal({
...updateUser(getGlobal(), currentUser.id, currentUser),
currentUserId: currentUser.id,
});
updateSessionUserId(currentUser.id);
}
function updateSessionUserId(currentUserId: string) {
const sessionUserAuth = localStorage.getItem(SESSION_USER_KEY);
if (!sessionUserAuth) return;
const userAuth = JSON.parse(sessionUserAuth);
userAuth.id = currentUserId;
localStorage.setItem(SESSION_USER_KEY, JSON.stringify(userAuth));
}