Attach Web Bots: Ask before uninstall (#4223)

This commit is contained in:
Alexander Zinchuk 2024-02-06 16:49:03 +01:00
parent 9a0c0e10dd
commit 9c8b2e4e40
4 changed files with 65 additions and 8 deletions

View File

@ -65,9 +65,7 @@ const AttachBotInstallModal: FC<OwnProps> = ({
label={tosLabel}
onCheck={setIsTosAccepted}
/>
{bot?.isInactive && bot.isForSideMenu && (
renderText(lang('WebBot.Account.Desclaimer.Desc', bot?.shortName), ['simple_markdown'])
)}
{renderText(lang('WebBot.Account.Desclaimer.Desc', bot?.shortName), ['simple_markdown'])}
</ConfirmDialog>
);
};

View File

@ -20,6 +20,7 @@ import { getColorLuma } from '../../../util/colors';
import { hexToRgb } from '../../../util/switchTheme';
import { extractCurrentThemeParams, validateHexColor } from '../../../util/themeStyle';
import { callApi } from '../../../api/gramjs';
import renderText from '../../common/helpers/renderText';
import useAppLayout from '../../../hooks/useAppLayout';
import useFlag from '../../../hooks/useFlag';
@ -31,6 +32,7 @@ import useSyncEffect from '../../../hooks/useSyncEffect';
import usePopupLimit from './hooks/usePopupLimit';
import useWebAppFrame from './hooks/useWebAppFrame';
import Icon from '../../common/Icon';
import Button from '../../ui/Button';
import ConfirmDialog from '../../ui/ConfirmDialog';
import DropdownMenu from '../../ui/DropdownMenu';
@ -114,6 +116,7 @@ const WebAppModal: FC<OwnProps & StateProps> = ({
const [shouldConfirmClosing, setShouldConfirmClosing] = useState(false);
const [isCloseModalOpen, openCloseModal, hideCloseModal] = useFlag(false);
const [isRemoveModalOpen, openRemoveModal, hideRemoveModal] = useFlag(false);
const [isLoaded, markLoaded, markUnloaded] = useFlag(false);
@ -226,10 +229,23 @@ const WebAppModal: FC<OwnProps & StateProps> = ({
}
}, [isPaymentModalOpen, paymentStatus, sendEvent, setWebAppPaymentSlug, webApp]);
const handleToggleClick = useLastCallback(() => {
const handleRemoveAttachBot = useLastCallback(() => {
toggleAttachBot({
botId: bot!.id,
isEnabled: !attachBot,
isEnabled: false,
});
closeWebApp();
});
const handleToggleClick = useLastCallback(() => {
if (attachBot) {
openRemoveModal();
return;
}
toggleAttachBot({
botId: bot!.id,
isEnabled: true,
});
});
@ -340,6 +356,7 @@ const WebAppModal: FC<OwnProps & StateProps> = ({
setShouldConfirmClosing(false);
hideCloseModal();
hideRemoveModal();
setPopupParameters(undefined);
setIsRequestingPhone(false);
setIsRequestingWriteAccess(false);
@ -350,7 +367,7 @@ const WebAppModal: FC<OwnProps & StateProps> = ({
setHeaderColor(themeParams.bg_color);
markUnloaded();
}
}, [hideCloseModal, isOpen, markUnloaded]);
}, [isOpen]);
function handleEvent(event: WebAppInboundEvent) {
const { eventType, eventData } = event;
@ -479,7 +496,7 @@ const WebAppModal: FC<OwnProps & StateProps> = ({
onClick={onTrigger}
ariaLabel="More actions"
>
<i className="icon icon-more" />
<Icon name="more" />
</Button>
);
}, [isMobile]);
@ -663,6 +680,14 @@ const WebAppModal: FC<OwnProps & StateProps> = ({
confirmIsDestructive
confirmLabel={lang('lng_bot_close_warning_sure')}
/>
<ConfirmDialog
isOpen={isRemoveModalOpen}
onClose={hideRemoveModal}
title={lang('BotRemoveFromMenuTitle')}
textParts={renderText(lang('BotRemoveFromMenu', bot?.firstName), ['simple_markdown'])}
confirmHandler={handleRemoveAttachBot}
confirmIsDestructive
/>
</Modal>
);
};

View File

@ -586,13 +586,46 @@ addActionHandler('requestWebView', async (global, actions, payload): Promise<voi
addActionHandler('requestAppWebView', async (global, actions, payload): Promise<void> => {
const {
botId, appName, startApp, theme, isWriteAllowed,
botId, appName, startApp, theme, isWriteAllowed, isFromConfirm,
tabId = getCurrentTabId(),
} = payload;
const bot = selectUser(global, botId);
if (!bot) return;
// Native clients require to install attach bots before using their named mini apps
const isAttachBotInstalled = Boolean(global.attachMenu.bots[bot.id]);
if (bot.isAttachBot && !isFromConfirm && !isAttachBotInstalled) {
const result = await callApi('loadAttachBot', {
bot,
});
if (result) {
const attachBot = result.bot;
global = getGlobal();
global = addUsers(global, buildCollectionByKey(result.users, 'id'));
setGlobal(global);
const shouldAskForTos = attachBot.isDisclaimerNeeded || attachBot.isForAttachMenu || attachBot.isForSideMenu;
if (shouldAskForTos) {
global = updateTabState(global, {
requestedAttachBotInstall: {
bot: attachBot,
onConfirm: {
action: 'requestAppWebView',
payload: {
...payload,
isFromConfirm: true,
},
},
},
}, tabId);
setGlobal(global);
return;
}
}
}
const botApp = await callApi('fetchBotApp', {
bot,
appName,

View File

@ -2563,6 +2563,7 @@ export interface ActionPayloads {
theme?: ApiThemeParameters;
startApp?: string;
isWriteAllowed?: boolean;
isFromConfirm?: boolean;
} & WithTabId;
setWebAppPaymentSlug: {
slug?: string;