201 lines
4.8 KiB
TypeScript

import {
addReducer, getDispatch, getGlobal, setGlobal,
} from '../../../lib/teact/teactn';
import { GlobalState } from '../../../global/types';
import {
ApiUpdate,
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';
addReducer('apiUpdate', (global, actions, update: ApiUpdate) => {
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();
}
if (actions.showDialog) {
actions.showDialog({ data: { ...update.error, hasErrorKey: true } });
}
break;
}
});
function onUpdateApiReady(global: GlobalState) {
const { hasWebNotifications, hasPushNotifications } = selectNotifySettings(global);
if (hasWebNotifications && hasPushNotifications) subscribe();
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':
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;
}
setGlobal({
...global,
isLoggingOut: false,
lastSyncTime: Date.now(),
});
break;
}
}
}
function onUpdateAuthorizationError(update: ApiUpdateAuthorizationError) {
setGlobal({
...getGlobal(),
authError: update.message,
});
}
function onUpdateConnectionState(update: ApiUpdateConnectionState) {
const { connectionState } = update;
const global = getGlobal();
setGlobal({
...global,
connectionState,
});
if (connectionState === 'connectionStateReady' && global.authState === 'authorizationStateReady') {
getDispatch().sync();
} else if (connectionState === 'connectionStateBroken') {
getDispatch().signOut();
}
}
function onUpdateSession(update: ApiUpdateSession) {
const { sessionData } = update;
const { authRememberMe, authState } = getGlobal();
const isEmpty = !sessionData || !sessionData.mainDcId;
if (!authRememberMe || authState !== 'authorizationStateReady' || isEmpty) {
return;
}
getDispatch().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: number) {
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));
}