Files
NeoTachyon/fe-app-tachyon/src/tachyon/tabs/diagnostic/partials/renderSupportModal.ts
T
Dushnilin affd8f7ca4 feat: add Boosty donation link to README and LuCI support modal
- Add Boosty badge to README.md and README.en.md headers
- Add Boosty as first donation option in support sections of both READMEs
- Add Boosty card (with orange border accent) to LuCI diagnostic support modal
- Add Russian translations for Boosty strings in po/ru/tachyon.po
2026-09-16 06:42:09 +03:00

303 lines
8.3 KiB
TypeScript

import { renderButton } from '../../../../partials';
import {
renderCheckIcon24,
renderCopyIcon24,
renderLinkIcon24,
} from '../../../../icons';
import { showToast } from '../../../../helpers/showToast';
interface CryptoItem {
name: string;
badge: string;
address: string;
}
const CRYPTO_LIST: CryptoItem[] = [
{
name: 'Bitcoin',
badge: 'BTC',
address: 'bc1q9ehdv7y9g948jejyflkq7xmau3tytgunxgh35h',
},
{
name: 'Ethereum',
badge: 'ETH / ERC-20',
address: '0x6CB7a4547eD62EF64990D5C6B5D9fdA58EB223E6',
},
{
name: 'TON',
badge: 'TON',
address: 'UQDPhLRjMz5KltDLACAT3YXXHDVEtIDOHky2i33ZIOtsMEoR',
},
{
name: 'Solana',
badge: 'SOL',
address: '3csTGaNeU9KjhCKHEKAU3XLS5UfVjEeBVhXihpsETZwh',
},
];
const CLOUDTIPS_URL = 'https://pay.cloudtips.ru/p/48c57581';
const BOOSTY_URL = 'https://boosty.to/tachyon';
async function copyTextToClipboard(text: string): Promise<boolean> {
try {
if (navigator.clipboard && window.isSecureContext) {
await navigator.clipboard.writeText(text);
return true;
}
} catch {
// Fallback to execCommand
}
try {
const ta = document.createElement('textarea');
ta.value = text;
ta.style.position = 'fixed';
ta.style.left = '-9999px';
ta.style.top = '0';
document.body.appendChild(ta);
ta.focus();
ta.select();
const successful = document.execCommand('copy');
document.body.removeChild(ta);
return successful;
} catch {
return false;
}
}
export function renderSupportModal(): void {
const introBlock = E(
'div',
{
style:
'margin-bottom: 16px; padding: 12px 14px; background: var(--background-color-secondary, rgba(0, 0, 0, 0.05)); border: 1px solid var(--border-color, rgba(128, 128, 128, 0.2)); border-radius: 6px; font-size: 13px; line-height: 1.5; color: var(--text-color-high, inherit);',
},
[
E(
'p',
{ style: 'margin: 0;' },
_(
'If Tachyon powers your daily networking and keeps your connection fast and secure, consider supporting ongoing development! ☕ 🧀 🌭',
),
),
],
);
// Boosty card (primary)
const boostyCard = E(
'div',
{
style:
'margin-bottom: 16px; padding: 14px; background: var(--background-color-secondary, rgba(0, 0, 0, 0.05)); border: 1px solid rgba(255, 106, 0, 0.35); border-radius: 6px;',
},
[
E(
'div',
{
style:
'display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px;',
},
[
E(
'div',
{ style: 'display: flex; flex-direction: column; gap: 2px;' },
[
E('div', { style: 'font-weight: bold; font-size: 14px;' }, [
'⭐ Boosty',
]),
E(
'div',
{
style:
'font-size: 12px; color: var(--text-color-medium, #888);',
},
_('Subscriptions, one-time donations and exclusives'),
),
],
),
renderButton({
classNames: ['cbi-button-action'],
icon: renderLinkIcon24,
text: _('Support on Boosty'),
onClick: () => {
window.open(BOOSTY_URL, '_blank', 'noopener,noreferrer');
},
}),
],
),
],
);
// CloudTips card
const cloudTipsCard = E(
'div',
{
style:
'margin-bottom: 16px; padding: 14px; background: var(--background-color-secondary, rgba(0, 0, 0, 0.05)); border: 1px solid var(--border-color, rgba(128, 128, 128, 0.2)); border-radius: 6px;',
},
[
E(
'div',
{
style:
'display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px;',
},
[
E(
'div',
{ style: 'display: flex; flex-direction: column; gap: 2px;' },
[
E('div', { style: 'font-weight: bold; font-size: 14px;' }, [
'💳 ',
_('Credit Cards / SBP / Tinkoff Pay'),
]),
E(
'div',
{
style:
'font-size: 12px; color: var(--text-color-medium, #888);',
},
_('Quick donation via Russian bank cards or SBP'),
),
],
),
renderButton({
classNames: ['cbi-button-action'],
icon: renderLinkIcon24,
text: _('Support on CloudTips'),
onClick: () => {
window.open(CLOUDTIPS_URL, '_blank', 'noopener,noreferrer');
},
}),
],
),
],
);
// Crypto list section
const cryptoItemsContainer = E('div', {
style: 'display: flex; flex-direction: column; gap: 10px;',
});
CRYPTO_LIST.forEach((item) => {
const addressCode = E(
'code',
{
style:
'font-family: monospace; font-size: 11px; word-break: break-all; flex: 1; padding: 6px 8px; background: var(--background-color-primary, rgba(0, 0, 0, 0.15)); border: 1px solid var(--border-color, rgba(128, 128, 128, 0.2)); border-radius: 4px; user-select: all; line-height: 1.4;',
},
item.address,
);
const copyBtn = renderButton({
classNames: ['cbi-button'],
icon: renderCopyIcon24,
text: _('Copy Address'),
onClick: async () => {
const ok = await copyTextToClipboard(item.address);
if (ok) {
copyBtn.replaceChildren(
renderCheckIcon24(),
document.createTextNode(' ' + _('Copied!')),
);
copyBtn.classList.add('cbi-button-apply');
setTimeout(() => {
copyBtn.replaceChildren(
renderCopyIcon24(),
document.createTextNode(' ' + _('Copy Address')),
);
copyBtn.classList.remove('cbi-button-apply');
}, 2000);
showToast(_('Address copied to clipboard'), 'success');
} else {
showToast(_('Failed to copy address'), 'error');
}
},
});
copyBtn.style.whiteSpace = 'nowrap';
copyBtn.style.flexShrink = '0';
const row = E(
'div',
{
style:
'padding: 10px 12px; background: var(--background-color-secondary, rgba(0, 0, 0, 0.05)); border: 1px solid var(--border-color, rgba(128, 128, 128, 0.2)); border-radius: 6px; display: flex; flex-direction: column; gap: 6px;',
},
[
E(
'div',
{
style: 'display: flex; align-items: center; gap: 8px;',
},
[
E(
'span',
{ style: 'font-weight: bold; font-size: 13px;' },
item.name,
),
E(
'span',
{
class: 'badge cbi-value-title',
style: 'font-size: 11px; padding: 2px 6px; opacity: 0.85;',
},
item.badge,
),
],
),
E(
'div',
{
style:
'display: flex; align-items: center; gap: 8px; flex-wrap: wrap;',
},
[addressCode, copyBtn],
),
],
);
cryptoItemsContainer.appendChild(row);
});
const cryptoSection = E('div', { style: 'margin-bottom: 16px;' }, [
E(
'div',
{
style:
'font-weight: bold; font-size: 14px; margin-bottom: 8px; display: flex; align-items: center; gap: 6px;',
},
['🪙 ', _('Cryptocurrency')],
),
cryptoItemsContainer,
]);
// Modal footer with Close button
const footer = E(
'div',
{
style:
'display: flex; justify-content: flex-end; padding-top: 12px; border-top: 1px solid var(--border-color, rgba(128, 128, 128, 0.2));',
},
[
renderButton({
classNames: ['cbi-button'],
text: _('Close'),
onClick: () => {
if (ui.hideModal) ui.hideModal();
},
}),
],
);
const modalContent = E(
'div',
{
style:
'max-width: 640px; width: 100%; box-sizing: border-box; padding: 4px;',
},
[introBlock, boostyCard, cloudTipsCard, cryptoSection, footer],
);
ui.showModal(`💖 ${_('Support Development')}`, modalContent);
}