bd0482c376
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.
108 lines
2.4 KiB
Svelte
108 lines
2.4 KiB
Svelte
<script lang="ts">
|
|
import { t } from '../lib/i18n/index.svelte';
|
|
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;
|
|
const version = __APP_VERSION__;
|
|
const c = $derived(aboutContent(app.locale, AUTO_MATCH_HOURS));
|
|
</script>
|
|
|
|
<div class="page">
|
|
<h1>{c.title}</h1>
|
|
<p>
|
|
{c.rulesPrefix}<a href={c.rulesUrl} target="_blank" rel="noopener noreferrer" onclick={onExternalLinkClick}>{c.rulesLink}</a>.
|
|
</p>
|
|
|
|
<section>
|
|
<h2>{c.randomTitle}</h2>
|
|
<p class="respect">❗️{c.randomRespect}</p>
|
|
<ul>
|
|
{#each c.random as item (item)}<li>{item}</li>{/each}
|
|
</ul>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>{c.friendsTitle}</h2>
|
|
<ul>
|
|
{#each c.friends as item (item)}<li>{item}</li>{/each}
|
|
</ul>
|
|
</section>
|
|
|
|
<p class="muted">{t('about.version', { v: version })}</p>
|
|
|
|
{#if !(app.profile?.isGuest ?? true)}
|
|
<button class="feedback" onclick={() => navigate('/feedback')}>
|
|
{t('feedback.title')}{#if app.feedbackReplyUnread}<span class="fbadge">1</span>{/if}
|
|
</button>
|
|
{/if}
|
|
</div>
|
|
|
|
<style>
|
|
.page {
|
|
padding: var(--pad);
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 14px;
|
|
}
|
|
h1 {
|
|
margin: 0;
|
|
font-size: 1.5rem;
|
|
}
|
|
h2 {
|
|
margin: 0 0 6px;
|
|
font-size: 1.05rem;
|
|
color: var(--text-muted);
|
|
}
|
|
section {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
}
|
|
ul {
|
|
margin: 0;
|
|
padding-left: 20px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
}
|
|
a {
|
|
color: var(--accent);
|
|
}
|
|
.respect {
|
|
margin: 0;
|
|
font-weight: 600;
|
|
}
|
|
.muted {
|
|
color: var(--text-muted);
|
|
font-size: 0.9rem;
|
|
margin: 0;
|
|
}
|
|
.feedback {
|
|
align-self: flex-start;
|
|
padding: 12px 18px;
|
|
border: 1px solid var(--accent);
|
|
background: var(--accent);
|
|
color: var(--accent-text);
|
|
border-radius: var(--radius);
|
|
font-weight: 600;
|
|
}
|
|
/* The reply badge sits on the accent button, so it inverts the accent colours. */
|
|
.fbadge {
|
|
display: inline-block;
|
|
margin-left: 8px;
|
|
min-width: 18px;
|
|
padding: 0 5px;
|
|
border-radius: 999px;
|
|
background: var(--accent-text);
|
|
color: var(--accent);
|
|
font-size: 0.78rem;
|
|
font-weight: 700;
|
|
line-height: 1.55;
|
|
text-align: center;
|
|
}
|
|
</style>
|