Update index.html

This commit is contained in:
Egor
2026-01-12 19:44:07 +03:00
committed by GitHub
parent fe9feaf65d
commit a2380b937c

View File

@@ -2852,21 +2852,28 @@
}
.daily-subscription-paused-notice {
margin-top: 12px;
padding: 12px;
background: rgba(var(--warning-rgb), 0.1);
border-radius: var(--radius);
border: 1px solid rgba(var(--warning-rgb), 0.2);
margin: 16px;
padding: 14px 16px;
background: linear-gradient(135deg, rgba(var(--warning-rgb), 0.12), rgba(var(--warning-rgb), 0.06));
border-radius: 12px;
border: 1px solid rgba(var(--warning-rgb), 0.25);
font-size: 13px;
line-height: 1.5;
color: var(--text-primary);
display: flex;
align-items: flex-start;
gap: 10px;
gap: 12px;
box-shadow: 0 2px 8px rgba(var(--warning-rgb), 0.08);
}
.daily-subscription-paused-notice .notice-icon {
font-size: 18px;
font-size: 20px;
line-height: 1;
flex-shrink: 0;
}
.daily-subscription-paused-notice span:last-child {
flex: 1;
}
:root[data-theme="dark"] .daily-subscription-status {
@@ -8515,6 +8522,19 @@
return div.innerHTML;
}
function getDaysWord(count, lang = 'ru') {
if (lang === 'en') {
return count === 1 ? 'day' : 'days';
}
// Russian: 1 день, 2-4 дня, 5-20 дней, 21 день, 22-24 дня, etc.
const n = Math.abs(count) % 100;
const n1 = n % 10;
if (n > 10 && n < 20) return 'дней';
if (n1 === 1) return 'день';
if (n1 >= 2 && n1 <= 4) return 'дня';
return 'дней';
}
function normalizeUrl(value) {
if (typeof value !== 'string') {
return null;
@@ -20670,16 +20690,32 @@
serverTags = `<span style="display: inline-block; padding: 2px 8px; background: var(--bg-tertiary, var(--bg-secondary)); border-radius: 12px; font-size: 11px;">🌍 Все серверы</span>`;
}
// В режиме смены тарифа показываем остаток дней
const remainingDaysText = preferredLanguage === 'en'
? `<b>${daysLeft} days</b> remaining — will be preserved on switch`
: `Осталось <b>${daysLeft} дн.</b> — сохранятся при смене`;
const remainingInfo = isInstantSwitchMode
? `<div style="display: flex; align-items: center; gap: 8px; margin-top: 12px; padding: 10px 12px; background: linear-gradient(135deg, rgba(59, 130, 246, 0.08) 0%, rgba(99, 102, 241, 0.05) 100%); border-radius: 10px; border: 1px solid rgba(59, 130, 246, 0.15);">
<span style="font-size: 15px;">⏰</span>
<span style="font-size: 12px; color: var(--text-primary); line-height: 1.4;">${remainingDaysText}</span>
</div>`
: '';
// Проверяем, суточный ли текущий тариф
const isCurrentDaily = currentTariff.is_daily ?? currentTariff.isDaily ?? false;
// В режиме смены тарифа показываем остаток
let remainingInfo = '';
if (isInstantSwitchMode) {
let remainingText = '';
if (isCurrentDaily) {
// Для суточного тарифа показываем другой текст
remainingText = preferredLanguage === 'en'
? 'Daily subscription — time is not transferred'
: 'Суточная подписка — время не переносится';
} else if (daysLeft > 0) {
// Для обычных тарифов показываем дни с правильным склонением
const daysWord = getDaysWord(daysLeft, preferredLanguage);
remainingText = preferredLanguage === 'en'
? `<b>${daysLeft} ${daysWord}</b> remaining — will be preserved on switch`
: `Осталось <b>${daysLeft} ${daysWord}</b> — сохранятся при смене`;
}
if (remainingText) {
remainingInfo = `<div style="display: flex; align-items: center; gap: 8px; margin-top: 12px; padding: 10px 12px; background: linear-gradient(135deg, rgba(59, 130, 246, 0.08) 0%, rgba(99, 102, 241, 0.05) 100%); border-radius: 10px; border: 1px solid rgba(59, 130, 246, 0.15);">
<span style="font-size: 15px;">${isCurrentDaily ? '🔄' : '⏰'}</span>
<span style="font-size: 12px; color: var(--text-primary); line-height: 1.4;">${remainingText}</span>
</div>`;
}
}
currentName.innerHTML = `
<div class="tariff-current-name">
@@ -20767,9 +20803,20 @@
${preferredLanguage === 'en' ? 'Instant tariff switch' : 'Мгновенная смена тарифа'}
</div>
<div style="font-size: 12px; color: var(--text-secondary); line-height: 1.5;">
${preferredLanguage === 'en'
? '<span style="color: #ea580c;">⬆️ Upgrade</span> = pay the difference • <span style="color: #16a34a;">⬇️ Downgrade</span> = free<br>Your remaining <b>' + daysLeft + ' days</b> will be preserved'
: '<span style="color: #ea580c;">⬆️ Повышение</span> = доплата • <span style="color: #16a34a;">⬇️ Понижение</span> = бесплатно<br>Ваши <b>' + daysLeft + ' дней</b> сохраняются'}
${(() => {
const isCurrentDailyTariff = currentTariff?.is_daily ?? currentTariff?.isDaily ?? false;
if (isCurrentDailyTariff) {
// Переключение с суточного тарифа - оплачивается новый тариф
return preferredLanguage === 'en'
? 'Switching from daily tariff requires full payment for the new tariff'
: 'Переключение с суточного тарифа — оплата нового тарифа полностью';
} else {
const daysWord = getDaysWord(daysLeft, preferredLanguage);
return preferredLanguage === 'en'
? '<span style="color: #ea580c;">⬆️ Upgrade</span> = pay the difference • <span style="color: #16a34a;">⬇️ Downgrade</span> = free<br>Your remaining <b>' + daysLeft + ' ' + daysWord + '</b> will be preserved'
: '<span style="color: #ea580c;">⬆️ Повышение</span> = доплата • <span style="color: #16a34a;">⬇️ Понижение</span> = бесплатно<br>Ваши <b>' + daysLeft + ' ' + daysWord + '</b> сохраняются';
}
})()}
</div>
</div>
</div>
@@ -20856,22 +20903,48 @@
${serverTags ? `<div style="display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px;">${serverTags}</div>` : ''}
</div>
<div class="instant-switch-tariff-cost">
${isDaily ? `
<span class="instant-switch-cost-badge" style="background: linear-gradient(135deg, #8b5cf6, #6366f1); color: white;">
<span style="font-size: 10px; display: block; text-transform: uppercase; opacity: 0.8;">${dailyLabel}</span>
${dailyPriceLabel || ''}
</span>
` : `
<span class="instant-switch-cost-badge ${isUpgrade ? 'upgrade' : 'free'}">
${isUpgrade
? `<span style="font-size: 10px; display: block; text-transform: uppercase; opacity: 0.8;">${upgradeLabel}</span>+${upgradeCostLabel}`
: freeLabel}
</span>
`}
${(() => {
const currentIsDaily = currentTariff?.is_daily ?? currentTariff?.isDaily ?? false;
const switchingFromDaily = currentIsDaily && !isDaily;
if (isDaily) {
// Переключение на суточный тариф
return `
<span class="instant-switch-cost-badge" style="background: linear-gradient(135deg, #8b5cf6, #6366f1); color: white;">
<span style="font-size: 10px; display: block; text-transform: uppercase; opacity: 0.8;">${dailyLabel}</span>
${dailyPriceLabel || ''}
</span>
`;
} else if (switchingFromDaily) {
// Переключение С суточного НА периодный - показываем "от X₽"
const fromLabel = preferredLanguage === 'en' ? 'from' : 'от';
return `
<span class="instant-switch-cost-badge upgrade">
<span style="font-size: 10px; display: block; text-transform: uppercase; opacity: 0.8;">${fromLabel}</span>
${upgradeCostLabel}
</span>
`;
} else if (isUpgrade) {
// Повышение тарифа - доплата
return `
<span class="instant-switch-cost-badge upgrade">
<span style="font-size: 10px; display: block; text-transform: uppercase; opacity: 0.8;">${upgradeLabel}</span>
+${upgradeCostLabel}
</span>
`;
} else {
// Понижение тарифа - бесплатно
return `
<span class="instant-switch-cost-badge free">
${freeLabel}
</span>
`;
}
})()}
</div>
`;
div.addEventListener('click', () => showInstantSwitchConfirm(tariff, isUpgrade, upgradeCost));
div.addEventListener('click', () => showInstantSwitchConfirm(tariff, isUpgrade, upgradeCost, currentTariff?.is_daily ?? currentTariff?.isDaily ?? false));
} else {
// Обычный режим покупки
const isDaily = tariff.is_daily ?? tariff.isDaily ?? false;
@@ -20999,8 +21072,9 @@
}
// Показать подтверждение мгновенной смены тарифа
async function showInstantSwitchConfirm(tariff, isUpgrade, estimatedCost) {
async function showInstantSwitchConfirm(tariff, isUpgrade, estimatedCost, currentIsDaily = false) {
const currentTariff = tariffsData?.current_tariff || tariffsData?.currentTariff;
const switchingFromDaily = currentIsDaily && !(tariff.is_daily ?? tariff.isDaily ?? false);
// Запрашиваем точную стоимость с сервера
try {
@@ -21053,6 +21127,9 @@
confirmUpgrade: preferredLanguage === 'en'
? `Switch to "${tariff.name}"?\n\nUpgrade cost: ${costLabel}\nYour balance: ${balanceLabel}`
: `Сменить тариф на «${tariff.name}»?\n\nДоплата: ${costLabel}\nВаш баланс: ${balanceLabel}`,
confirmFromDaily: preferredLanguage === 'en'
? `Switch to "${tariff.name}"?\n\nCost: ${costLabel}\n(Daily subscription time is not transferred)\nYour balance: ${balanceLabel}`
: `Сменить тариф на «${tariff.name}»?\n\nСтоимость: ${costLabel}\n(Время суточной подписки не переносится)\nВаш баланс: ${balanceLabel}`,
confirmDowngrade: preferredLanguage === 'en'
? `Switch to "${tariff.name}"?\n\nFree (downgrade)`
: `Сменить тариф на «${tariff.name}»?\n\nБесплатно (понижение тарифа)`,
@@ -21063,9 +21140,18 @@
};
// Используем кастомный попап или showConfirm
if (typeof tg.showConfirm === 'function' && hasEnough) {
const message = actualIsUpgrade ? txt.confirmUpgrade : txt.confirmDowngrade;
// Выбираем нужное сообщение в зависимости от типа перехода
let message;
if (switchingFromDaily) {
// Переход с суточного на периодный - особый текст
message = txt.confirmFromDaily;
} else if (actualIsUpgrade) {
message = txt.confirmUpgrade;
} else {
message = txt.confirmDowngrade;
}
if (typeof tg.showConfirm === 'function' && hasEnough) {
tg.showConfirm(message, async (confirmed) => {
if (confirmed) {
await executeInstantSwitch(tariff);
@@ -21073,8 +21159,6 @@
});
} else if (hasEnough) {
// Fallback на простой confirm
const message = actualIsUpgrade ? txt.confirmUpgrade : txt.confirmDowngrade;
if (confirm(message)) {
await executeInstantSwitch(tariff);
}