db17287113
The Android VK client's WebView ignores target=_blank and navigates the Mini App's own window to the target, stranding the player outside the game with no way back (the dictionary lookup, About/Feedback links, the ad banner and the bot-link modal fallbacks). vk-bridge 3.x has no method to open an external URL, so external links are routed through VK's own leave-VK redirect (vk.com/away.php), which the client intercepts natively and hands to the system browser. onExternalLinkClick moves from lib/telegram to a new lib/links that composes the Telegram and VK routers; iOS and desktop VK open _blank correctly and are left alone.
32 lines
1.6 KiB
TypeScript
32 lines
1.6 KiB
TypeScript
// Platform-aware external-link opening. Both Mini App hosts mishandle a plain target=_blank
|
|
// anchor: Telegram shows the WebView's generic "open this link?" confirmation, and the Android VK
|
|
// client navigates the app's own WebView to the target with no way back to the game. The helpers
|
|
// below route an external URL through the platform's escape hatch (Telegram's openLink, VK's
|
|
// away.php redirect) and leave the anchor's own navigation / window.open in effect elsewhere.
|
|
|
|
import { routeExternalLinkInTelegram } from './telegram';
|
|
import { routeExternalLinkInVK, vkOpenExternalUrl } from './vk';
|
|
|
|
/**
|
|
* onExternalLinkClick is the anchor click handler for external links. It resolves the clicked
|
|
* anchor with closest(), so it works both attached directly on an <a> and delegated on a container
|
|
* that renders links (e.g. {@html} markdown). Attach it as onclick on an external link or its
|
|
* container; outside Telegram and VK it is a no-op and the anchor's own target=_blank handles the
|
|
* click.
|
|
*/
|
|
export function onExternalLinkClick(e: MouseEvent): void {
|
|
const a = (e.target as HTMLElement | null)?.closest('a');
|
|
if (!a) return;
|
|
if (routeExternalLinkInTelegram(a) || routeExternalLinkInVK(a)) e.preventDefault();
|
|
}
|
|
|
|
/**
|
|
* openExternalUrl opens an external URL from code (no anchor to click): through VK's external
|
|
* redirect inside the Android VK client, else a plain new tab. Telegram callers try their native
|
|
* opener (telegramOpenLink) first and use this as the fallback.
|
|
*/
|
|
export function openExternalUrl(url: string): void {
|
|
if (vkOpenExternalUrl(url)) return;
|
|
if (typeof window !== 'undefined') window.open(url, '_blank');
|
|
}
|