Mini Apps: Use key as active tab id (#5268)

This commit is contained in:
zubiden 2024-12-06 19:43:59 +04:00 committed by Alexander Zinchuk
parent 87840629da
commit 00780ece5e
8 changed files with 61 additions and 52 deletions

View File

@ -7,7 +7,7 @@ import { getActions, getGlobal, withGlobal } from '../../../global';
import type { ApiUser } from '../../../api/types';
import type { WebApp } from '../../../global/types';
import { selectTabState, selectUser } from '../../../global/selectors';
import { selectActiveWebApp, selectTabState, selectUser } from '../../../global/selectors';
import buildClassName from '../../../util/buildClassName';
import { unique } from '../../../util/iteratees';
@ -126,7 +126,7 @@ export default memo(withGlobal(
const tabState = selectTabState(global);
const webApps = tabState.webApps;
const { botId } = webApps?.activeWebApp || {};
const { botId } = selectActiveWebApp(global) || {};
const { modalState, openedWebApps } = webApps || {};
const isMinimizedState = modalState === 'minimized';
const activeTabBot = botId ? selectUser(global, botId) : undefined;

View File

@ -15,6 +15,7 @@ import type { WebAppOutboundEvent } from '../../../types/webapp';
import { getWebAppKey } from '../../../global/helpers/bots';
import {
selectCurrentChat, selectTheme, selectUser,
selectWebApp,
} from '../../../global/selectors';
import buildClassName from '../../../util/buildClassName';
import buildStyle from '../../../util/buildStyle';
@ -103,8 +104,9 @@ const WebAppModal: FC<OwnProps & StateProps> = ({
}
const {
openedWebApps, activeWebApp, openedOrderedKeys, sessionKeys, isMoreAppsTabActive,
openedWebApps, activeWebAppKey, openedOrderedKeys, sessionKeys, isMoreAppsTabActive,
} = modal || {};
const activeWebApp = activeWebAppKey ? openedWebApps?.[activeWebAppKey] : undefined;
const {
isBackButtonVisible, headerColor, backgroundColor, isSettingsButtonVisible,
} = activeWebApp || {};
@ -664,7 +666,8 @@ const WebAppModal: FC<OwnProps & StateProps> = ({
export default memo(withGlobal<OwnProps>(
(global, { modal }): StateProps => {
const { botId: activeBotId } = modal?.activeWebApp || {};
const activeWebApp = modal?.activeWebAppKey ? selectWebApp(global, modal.activeWebAppKey) : undefined;
const { botId: activeBotId } = activeWebApp || {};
const attachBot = activeBotId ? global.attachMenu.bots[activeBotId] : undefined;
const bot = activeBotId ? selectUser(global, activeBotId) : undefined;

View File

@ -15,6 +15,7 @@ import { convertToApiChatType } from '../../../global/helpers';
import { getWebAppKey } from '../../../global/helpers/bots';
import {
selectCurrentChat, selectTabState, selectTheme, selectUser,
selectWebApp,
} from '../../../global/selectors';
import buildClassName from '../../../util/buildClassName';
import buildStyle from '../../../util/buildStyle';
@ -162,7 +163,7 @@ const WebAppModalTabContent: FC<OwnProps & StateProps> = ({
const [, setFullscreen, exitFullscreen] = useFullscreen(fullscreenElementRef, exitFullScreenCallback);
const activeWebApp = modal?.activeWebApp;
const activeWebApp = modal?.activeWebAppKey ? modal.openedWebApps[modal.activeWebAppKey] : undefined;
const activeWebAppName = activeWebApp?.appName;
const {
url, buttonText, headerColor, serverHeaderColorKey, serverHeaderColor, isBackButtonVisible,
@ -962,7 +963,8 @@ const WebAppModalTabContent: FC<OwnProps & StateProps> = ({
export default memo(withGlobal<OwnProps>(
(global, { modal }): StateProps => {
const { botId: activeBotId } = modal?.activeWebApp || {};
const activeWebApp = modal?.activeWebAppKey ? selectWebApp(global, modal.activeWebAppKey) : undefined;
const { botId: activeBotId } = activeWebApp || {};
const modalState = modal?.modalState;
const attachBot = activeBotId ? global.attachMenu.bots[activeBotId] : undefined;

View File

@ -136,10 +136,12 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
case 'updateWebViewResultSent':
Object.values(global.byTabId).forEach((tabState) => {
if (tabState.webApps.activeWebApp?.queryId === update.queryId) {
actions.resetDraftReplyInfo({ tabId: tabState.id });
actions.closeActiveWebApp({ tabId: tabState.id });
}
Object.entries(tabState.webApps.openedWebApps).forEach(([webAppKey, webApp]) => {
if (webApp.queryId === update.queryId) {
actions.resetDraftReplyInfo({ tabId: tabState.id });
actions.closeWebApp({ key: webAppKey, tabId: tabState.id });
}
});
});
break;

View File

@ -16,7 +16,9 @@ import {
updateWebApp,
} from '../../reducers/bots';
import { updateTabState } from '../../reducers/tabs';
import { selectCurrentMessageList, selectTabState, selectWebApp } from '../../selectors';
import {
selectActiveWebApp, selectCurrentMessageList, selectTabState, selectWebApp,
} from '../../selectors';
addActionHandler('openWebAppTab', (global, actions, payload): ActionReturnType => {
const {
@ -53,7 +55,7 @@ addActionHandler('openMoreAppsTab', (global, actions, payload): ActionReturnType
global = updateTabState(global, {
webApps: {
...tabState.webApps,
activeWebApp: undefined,
activeWebAppKey: undefined,
isMoreAppsTabActive: true,
},
}, tabId);
@ -68,14 +70,14 @@ addActionHandler('closeMoreAppsTab', (global, actions, payload): ActionReturnTyp
const openedWebApps = tabState.webApps.openedWebApps;
const openedWebAppsValues = Object.values(openedWebApps);
const openedWebAppsCount = openedWebAppsValues.length;
const openedWebAppsKeys = Object.keys(openedWebApps);
const openedWebAppsCount = openedWebAppsKeys.length;
global = updateTabState(global, {
webApps: {
...tabState.webApps,
isMoreAppsTabActive: false,
activeWebApp: openedWebAppsCount ? openedWebAppsValues[openedWebAppsCount - 1] : undefined,
activeWebAppKey: openedWebAppsCount ? openedWebAppsKeys[openedWebAppsCount - 1] : undefined,
isModalOpen: openedWebAppsCount > 0,
},
}, tabId);
@ -117,8 +119,7 @@ addActionHandler('changeWebAppModalState', (global, actions, payload): ActionRet
addActionHandler('setWebAppPaymentSlug', (global, actions, payload): ActionReturnType => {
const { tabId = getCurrentTabId() } = payload;
const tabState = selectTabState(global, tabId);
const activeWebApp = tabState.webApps.activeWebApp;
const activeWebApp = selectActiveWebApp(global, tabId);
if (!activeWebApp?.url) return undefined;
const key = getWebAppKey(activeWebApp);

View File

@ -5,7 +5,7 @@ import type {
import { getCurrentTabId } from '../../util/establishMultitabRole';
import { getWebAppKey } from '../helpers/bots';
import { selectTabState } from '../selectors';
import { selectActiveWebApp, selectTabState } from '../selectors';
import { updateTabState } from './tabs';
export function replaceInlineBotSettings<T extends GlobalState>(
@ -55,14 +55,9 @@ export function updateWebApp <T extends GlobalState>(
const updatedWebAppKey = getWebAppKey(updatedValue);
if (!updatedWebAppKey) return global;
const activeWebApp = currentTabState.webApps.activeWebApp;
const activeWebAppKey = activeWebApp && getWebAppKey(activeWebApp);
global = updateTabState(global, {
webApps: {
...currentTabState.webApps,
...updatedWebAppKey === activeWebAppKey && {
activeWebApp: updatedValue,
},
openedWebApps: {
...openedWebApps,
[updatedWebAppKey]: updatedValue,
@ -84,13 +79,11 @@ export function activateWebAppIfOpen<T extends GlobalState>(
return global;
}
const newActiveWebApp = openedWebApps[webAppKey];
global = updateTabState(global, {
webApps: {
...currentTabState.webApps,
isMoreAppsTabActive: false,
activeWebApp: newActiveWebApp,
activeWebAppKey: webAppKey,
modalState: 'maximized',
},
}, tabId);
@ -119,7 +112,7 @@ export function addWebAppToOpenList<T extends GlobalState>(
global = updateTabState(global, {
webApps: {
...currentTabState.webApps,
...makeActive && { activeWebApp: webApp },
...makeActive && { activeWebAppKey: key },
isMoreAppsTabActive: false,
isModalOpen: openModalIfNotOpen,
modalState: 'maximized',
@ -139,12 +132,11 @@ export function removeActiveWebAppFromOpenList<T extends GlobalState>(
global: T, ...[tabId = getCurrentTabId()]: TabArgs<T>
): T {
const currentTabState = selectTabState(global, tabId);
const activeWebAppKey = currentTabState.webApps.activeWebAppKey;
if (!currentTabState.webApps.activeWebApp) return global;
if (!activeWebAppKey) return global;
const key = getWebAppKey(currentTabState.webApps.activeWebApp);
return removeWebAppFromOpenList(global, key, false, tabId);
return removeWebAppFromOpenList(global, activeWebAppKey, false, tabId);
}
export function removeWebAppFromOpenList<T extends GlobalState>(
@ -152,7 +144,7 @@ export function removeWebAppFromOpenList<T extends GlobalState>(
...[tabId = getCurrentTabId()]: TabArgs<T>
): T {
const currentTabState = selectTabState(global, tabId);
const openedWebApps = currentTabState.webApps.openedWebApps;
const { openedWebApps, openedOrderedKeys, activeWebAppKey } = currentTabState.webApps;
const webApp = openedWebApps[key];
if (!webApp) return global;
@ -163,26 +155,24 @@ export function removeWebAppFromOpenList<T extends GlobalState>(
const updatedOpenedWebApps = { ...openedWebApps };
const removingWebAppKey = getWebAppKey(webApp);
let newOpenedKeys = currentTabState.webApps.openedOrderedKeys;
let newOpenedKeys = openedOrderedKeys;
if (removingWebAppKey) {
delete updatedOpenedWebApps[removingWebAppKey];
newOpenedKeys = currentTabState.webApps.openedOrderedKeys.filter((k) => k !== removingWebAppKey);
newOpenedKeys = openedOrderedKeys.filter((k) => k !== removingWebAppKey);
}
const activeWebApp = currentTabState.webApps.activeWebApp;
const isRemovedAppActive = activeWebAppKey === getWebAppKey(webApp);
const isRemovedAppActive = activeWebApp && (getWebAppKey(activeWebApp) === getWebAppKey(webApp));
const openedWebAppsValues = Object.values(updatedOpenedWebApps);
const openedWebAppsCount = openedWebAppsValues.length;
const openedWebAppsKeys = Object.keys(updatedOpenedWebApps);
const openedWebAppsCount = openedWebAppsKeys.length;
global = updateTabState(global, {
webApps: {
...currentTabState.webApps,
...isRemovedAppActive && {
activeWebApp: openedWebAppsCount
? openedWebAppsValues[openedWebAppsCount - 1] : undefined,
activeWebAppKey: openedWebAppsCount
? openedWebAppsKeys[openedWebAppsCount - 1] : undefined,
},
openedWebApps: updatedOpenedWebApps,
openedOrderedKeys: newOpenedKeys,
@ -203,8 +193,7 @@ export function clearOpenedWebApps<T extends GlobalState>(
const webAppsNotAllowedToClose = Object.fromEntries(
Object.entries(currentTabState.webApps.openedWebApps).filter(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
([url, webApp]) => webApp.shouldConfirmClosing,
([, webApp]) => webApp.shouldConfirmClosing,
),
);
@ -215,7 +204,7 @@ export function clearOpenedWebApps<T extends GlobalState>(
return updateTabState(global, {
webApps: {
...currentTabState.webApps,
activeWebApp: undefined,
activeWebAppKey: undefined,
openedWebApps: {},
openedOrderedKeys: [],
sessionKeys: [],
@ -223,22 +212,25 @@ export function clearOpenedWebApps<T extends GlobalState>(
}, tabId);
}
const currentActiveWebApp = currentTabState.webApps.activeWebApp;
const currentActiveWebApp = selectActiveWebApp(global, tabId);
const newActiveWebApp = currentActiveWebApp?.shouldConfirmClosing
? currentActiveWebApp : webAppsNotAllowedToCloseValues[0];
newActiveWebApp.isCloseModalOpen = true;
const newActiveWebAppKey = getWebAppKey(newActiveWebApp);
const key = getWebAppKey(newActiveWebApp);
if (key) webAppsNotAllowedToClose[key] = newActiveWebApp;
const newOpenedKeys = currentTabState.webApps.openedOrderedKeys.filter((k) => k in webAppsNotAllowedToClose);
if (newActiveWebAppKey) {
webAppsNotAllowedToClose[newActiveWebAppKey] = {
...newActiveWebApp,
isCloseModalOpen: true,
};
}
const newOpenedKeys = currentTabState.webApps.openedOrderedKeys.filter((k) => webAppsNotAllowedToClose[k]);
return updateTabState(global, {
webApps: {
...currentTabState.webApps,
activeWebApp: newActiveWebApp,
activeWebAppKey: newActiveWebAppKey,
isMoreAppsTabActive: false,
openedWebApps: webAppsNotAllowedToClose,
openedOrderedKeys: newOpenedKeys,

View File

@ -156,3 +156,12 @@ export function selectWebApp<T extends GlobalState>(
) {
return selectTabState(global, tabId).webApps.openedWebApps[key];
}
export function selectActiveWebApp<T extends GlobalState>(
global: T, ...[tabId = getCurrentTabId()]: TabArgs<T>
) {
const activeWebAppKey = selectTabState(global, tabId).webApps.activeWebAppKey;
if (!activeWebAppKey) return undefined;
return selectWebApp(global, activeWebAppKey, tabId);
}

View File

@ -695,7 +695,7 @@ export type TabState = {
};
webApps: {
activeWebApp?: WebApp;
activeWebAppKey?: string;
openedOrderedKeys: string[];
sessionKeys: string[];
openedWebApps: Record<string, WebApp>;