feat(ui): route all in-app external links through Telegram openLink
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Successful in 49s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 59s

Extend the openLink routing from the dictionary lookup to every external
link shown inside the Mini App, so none triggers the WebView's 'open this
link?' confirmation. A shared onExternalLinkClick handler resolves the anchor
via closest() (so it also works delegated on {@html} content), backed by a
pure routeExternalLinkInTelegram decision: only inside Telegram, only an
external http(s) target=_blank link, excluding same-origin/in-app and t.me
links (t.me keeps openTelegramLink). Applied to the word-check lookup, the
About rules link, the Feedback operator-reply links, and the feature-gated
announcement banner.

Outside Telegram every anchor keeps its native target=_blank.
This commit is contained in:
Ilia Denisov
2026-06-15 18:29:53 +02:00
parent 8e0d7f9e17
commit bd0482c376
7 changed files with 92 additions and 12 deletions
+2 -1
View File
@@ -3,6 +3,7 @@
import { app } from '../lib/app.svelte';
import { navigate } from '../lib/router.svelte';
import { aboutContent } from '../lib/aboutContent';
import { onExternalLinkClick } from '../lib/telegram';
// The auto-match move clock (mirrors backend game.DefaultTurnTimeout = 24h).
const AUTO_MATCH_HOURS = 24;
@@ -13,7 +14,7 @@
<div class="page">
<h1>{c.title}</h1>
<p>
{c.rulesPrefix}<a href={c.rulesUrl} target="_blank" rel="noopener noreferrer">{c.rulesLink}</a>.
{c.rulesPrefix}<a href={c.rulesUrl} target="_blank" rel="noopener noreferrer" onclick={onExternalLinkClick}>{c.rulesLink}</a>.
</p>
<section>
+2 -1
View File
@@ -7,6 +7,7 @@
import { connection } from '../lib/connection.svelte';
import { clientChannel } from '../lib/channel';
import { attachmentError, linkify, MAX_BODY } from '../lib/feedback';
import { onExternalLinkClick } from '../lib/telegram';
import type { FeedbackState } from '../lib/model';
// The feedback screen: a message (+ optional single attachment) the player sends to
@@ -123,7 +124,7 @@
{#if view?.reply}
<section class="reply">
<h2>{t('feedback.replyTitle')}</h2>
<p class="replybody">{#each replySegments as seg, i (i)}{#if seg.href}<a href={seg.href} target="_blank" rel="noopener noreferrer">{seg.text}</a>{:else}{seg.text}{/if}{/each}</p>
<p class="replybody">{#each replySegments as seg, i (i)}{#if seg.href}<a href={seg.href} target="_blank" rel="noopener noreferrer" onclick={onExternalLinkClick}>{seg.text}</a>{:else}{seg.text}{/if}{/each}</p>
</section>
{/if}
</div>