Check active Web K tabs (#6319)
This commit is contained in:
parent
c011a436f9
commit
750b45ed1c
@ -1296,9 +1296,11 @@
|
||||
"SettingsPasscodeStart2" = "Note: if you forget your local passcode, you'll need to log out of Telegram Web A and log in again.";
|
||||
"CurrentPasswordPlaceholder" = "Current password";
|
||||
"ChangeYourProfilePicture" = "Change your profile picture";
|
||||
"TooManyTabsTitle" = "Such error, many tabs";
|
||||
"TooManyTabsDescription" = "Telegram supports only one active tab with the app.\nPlease reload this page to continue using this tab or close it.";
|
||||
"TooManyTabsReload" = "Reload app";
|
||||
"AppInactiveOtherClientTitle" = "Many sessions. So conflict.";
|
||||
"AppInactiveOtherClientDescription" = "Please, keep only one version of the app open.\nReload this page to continue using this tab or close it.";
|
||||
"AppInactiveAuthTitle" = "Many logins. So conflict.";
|
||||
"AppInactiveAuthDescription" = "Please, keep only one tab open during login.\nReload this page to continue using this tab or close it.";
|
||||
"AppInactiveReload" = "Reload App";
|
||||
"SlowmodeEnabled" = "Slowmode enabled";
|
||||
"SomethingWentWrong" = "Something went wrong";
|
||||
"MediaViewDownloading" = "{count}% downloading...";
|
||||
|
||||
@ -23,8 +23,7 @@ import { updateSizes } from '../util/windowSize';
|
||||
|
||||
import useTauriDrag from '../hooks/tauri/useTauriDrag';
|
||||
import useAppLayout from '../hooks/useAppLayout';
|
||||
import useFlag from '../hooks/useFlag';
|
||||
import usePreviousDeprecated from '../hooks/usePreviousDeprecated';
|
||||
import usePrevious from '../hooks/usePrevious';
|
||||
|
||||
// import Test from './test/TestLocale';
|
||||
import Auth from './auth/Auth';
|
||||
@ -40,7 +39,7 @@ type StateProps = {
|
||||
authState: GlobalState['authState'];
|
||||
isScreenLocked?: boolean;
|
||||
hasPasscode?: boolean;
|
||||
isInactiveAuth?: boolean;
|
||||
inactiveReason?: 'auth' | 'otherClient';
|
||||
hasWebAuthTokenFailed?: boolean;
|
||||
isTestServer?: boolean;
|
||||
theme: ThemeKey;
|
||||
@ -61,12 +60,11 @@ const App: FC<StateProps> = ({
|
||||
authState,
|
||||
isScreenLocked,
|
||||
hasPasscode,
|
||||
isInactiveAuth,
|
||||
inactiveReason,
|
||||
hasWebAuthTokenFailed,
|
||||
isTestServer,
|
||||
theme,
|
||||
}) => {
|
||||
const [isInactive, markInactive, unmarkInactive] = useFlag(false);
|
||||
const { isMobile } = useAppLayout();
|
||||
const isMobileOs = PLATFORM_ENV === 'iOS' || PLATFORM_ENV === 'Android';
|
||||
|
||||
@ -135,7 +133,7 @@ const App: FC<StateProps> = ({
|
||||
let activeKey: AppScreens;
|
||||
let page: UiLoaderPage | undefined;
|
||||
|
||||
if (isInactive) {
|
||||
if (inactiveReason) {
|
||||
activeKey = AppScreens.inactive;
|
||||
} else if (isScreenLocked) {
|
||||
page = 'lock';
|
||||
@ -193,16 +191,14 @@ const App: FC<StateProps> = ({
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (isInactiveAuth) {
|
||||
if (inactiveReason) {
|
||||
document.title = INACTIVE_PAGE_TITLE;
|
||||
markInactive();
|
||||
} else {
|
||||
document.title = ACTIVE_PAGE_TITLE;
|
||||
unmarkInactive();
|
||||
}
|
||||
}, [isInactiveAuth, markInactive, unmarkInactive]);
|
||||
}, [inactiveReason]);
|
||||
|
||||
const prevActiveKey = usePreviousDeprecated(activeKey);
|
||||
const prevActiveKey = usePrevious(activeKey);
|
||||
|
||||
function renderContent() {
|
||||
switch (activeKey) {
|
||||
@ -213,7 +209,7 @@ const App: FC<StateProps> = ({
|
||||
case AppScreens.lock:
|
||||
return <LockScreen isLocked={isScreenLocked} />;
|
||||
case AppScreens.inactive:
|
||||
return <AppInactive />;
|
||||
return <AppInactive inactiveReason={inactiveReason!} />;
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,7 +251,7 @@ export default withGlobal(
|
||||
authState: global.authState,
|
||||
isScreenLocked: global.passcode?.isScreenLocked,
|
||||
hasPasscode: global.passcode?.hasPasscode,
|
||||
isInactiveAuth: selectTabState(global).isInactive,
|
||||
inactiveReason: selectTabState(global).inactiveReason,
|
||||
hasWebAuthTokenFailed: global.hasWebAuthTokenFailed || global.hasWebAuthTokenPasswordRequired,
|
||||
theme: selectTheme(global),
|
||||
isTestServer: global.config?.isTestServer,
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import type { FC } from '../../lib/teact/teact';
|
||||
import { useCallback } from '../../lib/teact/teact';
|
||||
import renderText from '../common/helpers/renderText';
|
||||
|
||||
import useHistoryBack from '../../hooks/useHistoryBack';
|
||||
import useLang from '../../hooks/useLang';
|
||||
import useLastCallback from '../../hooks/useLastCallback';
|
||||
|
||||
import Button from '../ui/Button';
|
||||
|
||||
@ -9,10 +10,16 @@ import './AppInactive.scss';
|
||||
|
||||
import appInactivePath from '../../assets/app-inactive.png';
|
||||
|
||||
const AppInactive: FC = () => {
|
||||
const handleReload = useCallback(() => {
|
||||
type OwnProps = {
|
||||
inactiveReason: 'auth' | 'otherClient';
|
||||
};
|
||||
|
||||
const AppInactive = ({ inactiveReason }: OwnProps) => {
|
||||
const lang = useLang();
|
||||
|
||||
const handleReload = useLastCallback(() => {
|
||||
window.location.reload();
|
||||
}, []);
|
||||
});
|
||||
|
||||
useHistoryBack({
|
||||
isActive: true,
|
||||
@ -24,15 +31,18 @@ const AppInactive: FC = () => {
|
||||
<div id="AppInactive">
|
||||
<div className="content">
|
||||
<img src={appInactivePath} alt="" />
|
||||
<h3 className="title">Such error, many tabs</h3>
|
||||
<h3 className="title">
|
||||
{inactiveReason === 'auth' ? lang('AppInactiveAuthTitle') : lang('AppInactiveOtherClientTitle')}
|
||||
</h3>
|
||||
<div className="description">
|
||||
Telegram supports only one active tab with the app.
|
||||
<br />
|
||||
Please reload this page to continue using this tab or close it.
|
||||
{renderText(
|
||||
lang(inactiveReason === 'auth' ? 'AppInactiveAuthDescription' : 'AppInactiveOtherClientDescription'),
|
||||
['br'],
|
||||
)}
|
||||
</div>
|
||||
<div className="actions">
|
||||
<Button isText ripple onClick={handleReload}>
|
||||
Reload app
|
||||
{lang('AppInactiveReload')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -67,6 +67,7 @@ export const AUTODOWNLOAD_FILESIZE_MB_LIMITS = [1, 5, 10, 50, 100, 500];
|
||||
export const DATA_BROADCAST_CHANNEL_PREFIX = 'tt-global';
|
||||
export const ESTABLISH_BROADCAST_CHANNEL_PREFIX = 'tt-establish';
|
||||
export const MULTITAB_LOCALSTORAGE_KEY_PREFIX = 'tt-multitab';
|
||||
export const INTERCLIENT_BROADCAST_CHANNEL = 'tgweb';
|
||||
export const DC_IDS = [1, 2, 3, 4, 5] as const;
|
||||
|
||||
export const DOWNLOAD_WORKERS = 16;
|
||||
|
||||
@ -183,7 +183,7 @@ function onUpdateAuthorizationState<T extends GlobalState>(global: T, update: Ap
|
||||
};
|
||||
Object.values(global.byTabId).forEach(({ id: tabId }) => {
|
||||
global = updateTabState(global, {
|
||||
isInactive: false,
|
||||
inactiveReason: undefined,
|
||||
}, tabId);
|
||||
});
|
||||
setGlobal(global);
|
||||
|
||||
@ -115,7 +115,7 @@ addActionHandler('init', (global, actions, payload): ActionReturnType => {
|
||||
Object.values(global.byTabId).forEach(({ id: otherTabId }) => {
|
||||
if (otherTabId === tabId) return;
|
||||
global = updateTabState(global, {
|
||||
isInactive: true,
|
||||
inactiveReason: 'auth',
|
||||
}, otherTabId);
|
||||
});
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ export type TabState = {
|
||||
id: number;
|
||||
isBlurred?: boolean;
|
||||
isMasterTab: boolean;
|
||||
isInactive?: boolean;
|
||||
inactiveReason?: 'auth' | 'otherClient';
|
||||
shouldPreventComposerAnimation?: boolean;
|
||||
inviteHash?: string;
|
||||
canInstall?: boolean;
|
||||
|
||||
@ -15,6 +15,7 @@ import { selectTabState } from './global/selectors';
|
||||
import { selectSharedSettings } from './global/selectors/sharedState';
|
||||
import { betterView } from './util/betterView';
|
||||
import { IS_TAURI } from './util/browser/globalEnvironment';
|
||||
import listenOtherClients from './util/browser/listenOtherClients';
|
||||
import { requestGlobal, subscribeToMultitabBroadcastChannel } from './util/browser/multitab';
|
||||
import { establishMultitabRole, subscribeToMasterChange } from './util/establishMultitabRole';
|
||||
import { initGlobal } from './util/init';
|
||||
@ -51,6 +52,7 @@ async function init() {
|
||||
if (!(window as any).isCompatTestPassed) return;
|
||||
|
||||
checkAndAssignPermanentWebVersion();
|
||||
listenOtherClients();
|
||||
|
||||
subscribeToMultitabBroadcastChannel();
|
||||
await requestGlobal(APP_VERSION);
|
||||
|
||||
8
src/types/language.d.ts
vendored
8
src/types/language.d.ts
vendored
@ -1102,9 +1102,11 @@ export interface LangPair {
|
||||
'SettingsPasscodeStart2': undefined;
|
||||
'CurrentPasswordPlaceholder': undefined;
|
||||
'ChangeYourProfilePicture': undefined;
|
||||
'TooManyTabsTitle': undefined;
|
||||
'TooManyTabsDescription': undefined;
|
||||
'TooManyTabsReload': undefined;
|
||||
'AppInactiveOtherClientTitle': undefined;
|
||||
'AppInactiveOtherClientDescription': undefined;
|
||||
'AppInactiveAuthTitle': undefined;
|
||||
'AppInactiveAuthDescription': undefined;
|
||||
'AppInactiveReload': undefined;
|
||||
'SlowmodeEnabled': undefined;
|
||||
'SomethingWentWrong': undefined;
|
||||
'VideoPlayerBuffering': undefined;
|
||||
|
||||
22
src/util/browser/listenOtherClients.ts
Normal file
22
src/util/browser/listenOtherClients.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { getGlobal, setGlobal } from '../../global';
|
||||
|
||||
import { APP_CODE_NAME, INTERCLIENT_BROADCAST_CHANNEL } from '../../config';
|
||||
import { updateTabState } from '../../global/reducers/tabs';
|
||||
import { selectTabState } from '../../global/selectors';
|
||||
|
||||
export default function listenOtherClients() {
|
||||
const channel = new BroadcastChannel(INTERCLIENT_BROADCAST_CHANNEL);
|
||||
|
||||
channel.addEventListener('message', (event) => {
|
||||
if (event.data !== APP_CODE_NAME) {
|
||||
let global = getGlobal();
|
||||
const tabState = selectTabState(global);
|
||||
global = updateTabState(global, {
|
||||
inactiveReason: 'otherClient',
|
||||
}, tabState.id);
|
||||
setGlobal(global);
|
||||
}
|
||||
});
|
||||
|
||||
channel.postMessage(APP_CODE_NAME);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user