feat(telegram): native dialogs for confirms and deep-link notices
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 15s
CI / ui (pull_request) Successful in 56s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m19s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 15s
CI / ui (pull_request) Successful in 56s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m19s
Inside the Mini App, route the destructive confirmations (resign, block, unfriend) through Telegram's native showConfirm, and present the deep-link info modals (stale invite, welcome-on-redeem) as a native showPopup whose button opens the bot chat. Outside Telegram, or on a client predating the dialogs, the existing in-app Modal is used unchanged; offline also keeps the modal so the action retains its disabled state. Adds showConfirm/showPopup wrappers to telegram.ts and a pure popup-params builder (nativedialogs.ts) with unit tests; the deep-link modal components choose native vs in-app via an effect gated on insideTelegram + dialog availability.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
import { GatewayError } from '../lib/client';
|
||||
import { t } from '../lib/i18n/index.svelte';
|
||||
import { friendCodeParam, shareLink } from '../lib/deeplink';
|
||||
import { shareTelegramLink } from '../lib/telegram';
|
||||
import { insideTelegram, shareTelegramLink, telegramDialogsAvailable, telegramShowConfirm } from '../lib/telegram';
|
||||
import type { AccountRef, FriendCode, RobotBlockEntry } from '../lib/model';
|
||||
|
||||
let friends = $state<AccountRef[]>([]);
|
||||
@@ -66,20 +66,36 @@
|
||||
|
||||
// confirmBlock / confirmUnfriend run the pending action once its modal is
|
||||
// accepted, then clear the target and the revealed row.
|
||||
function confirmBlock(): void {
|
||||
const target = blockTarget;
|
||||
function confirmBlock(target = blockTarget): void {
|
||||
blockTarget = null;
|
||||
revealedId = null;
|
||||
if (target) void blockUser(target.accountId);
|
||||
}
|
||||
|
||||
function confirmUnfriend(): void {
|
||||
const target = unfriendTarget;
|
||||
function confirmUnfriend(target = unfriendTarget): void {
|
||||
unfriendTarget = null;
|
||||
revealedId = null;
|
||||
if (target) void remove(target.accountId);
|
||||
}
|
||||
|
||||
// onBlockClick / onUnfriendClick: inside the Mini App (and online) confirm with Telegram's native
|
||||
// dialog and act on accept; otherwise open the in-app confirm modal (the offline / web path).
|
||||
async function onBlockClick(f: AccountRef): Promise<void> {
|
||||
if (connection.online && insideTelegram() && telegramDialogsAvailable()) {
|
||||
if (await telegramShowConfirm(`${t('friends.blockConfirm')}\n${f.displayName}`)) confirmBlock(f);
|
||||
return;
|
||||
}
|
||||
blockTarget = f;
|
||||
}
|
||||
|
||||
async function onUnfriendClick(f: AccountRef): Promise<void> {
|
||||
if (connection.online && insideTelegram() && telegramDialogsAvailable()) {
|
||||
if (await telegramShowConfirm(`${t('friends.unfriendConfirm')}\n${f.displayName}`)) confirmUnfriend(f);
|
||||
return;
|
||||
}
|
||||
unfriendTarget = f;
|
||||
}
|
||||
|
||||
// While a friend row is slid open, a tap anywhere outside its action buttons
|
||||
// closes it again. Taps on a kebab are skipped so its own toggle stays in charge.
|
||||
$effect(() => {
|
||||
@@ -216,8 +232,8 @@
|
||||
{#each friends as f (f.accountId)}
|
||||
<div class="rowwrap" class:revealed={revealedId === f.accountId}>
|
||||
<div class="acts">
|
||||
<button class="iconbtn" onclick={() => (blockTarget = f)} disabled={!connection.online} aria-label={t('friends.block')}>🚫</button>
|
||||
<button class="iconbtn" onclick={() => (unfriendTarget = f)} disabled={!connection.online} aria-label={t('friends.unfriend')}>✖️</button>
|
||||
<button class="iconbtn" onclick={() => onBlockClick(f)} disabled={!connection.online} aria-label={t('friends.block')}>🚫</button>
|
||||
<button class="iconbtn" onclick={() => onUnfriendClick(f)} disabled={!connection.online} aria-label={t('friends.unfriend')}>✖️</button>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="who">{f.displayName}</span>
|
||||
@@ -264,7 +280,7 @@
|
||||
<p class="confirm-name">{blockTarget.displayName}</p>
|
||||
<div class="confirm-row">
|
||||
<button class="cancel" onclick={() => (blockTarget = null)}>{t('common.cancel')}</button>
|
||||
<button class="danger" onclick={confirmBlock} disabled={!connection.online}>{t('friends.block')}</button>
|
||||
<button class="danger" onclick={() => confirmBlock()} disabled={!connection.online}>{t('friends.block')}</button>
|
||||
</div>
|
||||
</Modal>
|
||||
{/if}
|
||||
@@ -273,7 +289,7 @@
|
||||
<p class="confirm-name">{unfriendTarget.displayName}</p>
|
||||
<div class="confirm-row">
|
||||
<button class="cancel" onclick={() => (unfriendTarget = null)}>{t('common.cancel')}</button>
|
||||
<button class="danger" onclick={confirmUnfriend} disabled={!connection.online}>{t('friends.unfriend')}</button>
|
||||
<button class="danger" onclick={() => confirmUnfriend()} disabled={!connection.online}>{t('friends.unfriend')}</button>
|
||||
</div>
|
||||
</Modal>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user