// Application State const state = { currentTab: 'transfer', balance: 664.85, carouselIndex: 0, isCarouselPaused: false }; // DOM Elements const infoBlock = document.getElementById('infoBlock'); const navButtons = document.querySelectorAll('.nav-btn'); const carouselTrack = document.getElementById('carouselTrack'); const carouselIndicators = document.getElementById('carouselIndicators'); const walletAddress = document.getElementById('walletAddress'); const copyAddressBtn = document.getElementById('copyAddressBtn'); const addressFeedback = document.getElementById('addressFeedback'); // Tab Content Templates const tabContent = { transfer: `
`, store: `
Purchased Subscriptions
LVL1
Starter Pack
Basic features access
✓ Active until 15 Jan 2025
Available Subscriptions
LVL2
Pro Access
Premium features + priority
LVL3
Elite Member
All features + exclusive perks
LVL4
Legend Status
Ultimate access + lifetime perks
`, history: `
Deposit
Today, 14:32
+500.00₽
Subscription
Yesterday, 09:15
-250.00₽
Transfer Out
Dec 24, 18:45
-150.00₽
Task Reward
Dec 22, 11:20
+100.00₽
`, tasks: `
12
Invited
89
Likes
34
Comments
7
Reposts
vk.com/uwu.chan
YUfs1if421Hf
Available Tasks
Subscribe to UwU Chan
+100₽ reward
Subscribe to Shy Chan
+100₽ reward
Subscribe to Esco Chan
+100₽ reward
` }; // Initialize Application function init() { renderTab('transfer'); initCarousel(); initNavigation(); initAddressCopy(); } // Render Tab Content function renderTab(tabName) { state.currentTab = tabName; infoBlock.innerHTML = tabContent[tabName]; // Re-attach event listeners for dynamic content if (tabName === 'transfer') { initTransferForm(); } } // Navigation function initNavigation() { navButtons.forEach(btn => { btn.addEventListener('click', () => { const tab = btn.dataset.tab; // Update active states navButtons.forEach(b => b.classList.remove('active')); btn.classList.add('active'); // Render new tab with animation infoBlock.style.opacity = '0'; infoBlock.style.transform = 'translateY(10px)'; infoBlock.style.transition = 'all 0.2s ease'; setTimeout(() => { renderTab(tab); infoBlock.style.opacity = '1'; infoBlock.style.transform = 'translateY(0)'; }, 150); }); }); } // Carousel Functionality function initCarousel() { const slides = carouselTrack.children; const slideCount = slides.length; // Create indicators carouselIndicators.innerHTML = ''; for (let i = 0; i < slideCount; i++) { const indicator = document.createElement('div'); indicator.className = `indicator ${i === 0 ? 'active' : ''}`; indicator.addEventListener('click', () => goToSlide(i)); carouselIndicators.appendChild(indicator); } // Touch handling let startX = 0; let currentX = 0; let isDragging = false; carouselTrack.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; isDragging = true; state.isCarouselPaused = true; }, { passive: true }); carouselTrack.addEventListener('touchmove', (e) => { if (!isDragging) return; currentX = e.touches[0].clientX; const diff = startX - currentX; const offset = -state.carouselIndex * 100 - (diff / carouselTrack.offsetWidth) * 100; carouselTrack.style.transition = 'none'; carouselTrack.style.transform = `translateX(${offset}%)`; }, { passive: true }); carouselTrack.addEventListener('touchend', (e) => { if (!isDragging) return; isDragging = false; state.isCarouselPaused = false; const diff = startX - currentX; const threshold = carouselTrack.offsetWidth * 0.25; carouselTrack.style.transition = ''; if (Math.abs(diff) > threshold) { if (diff > 0 && state.carouselIndex < slideCount - 1) { goToSlide(state.carouselIndex + 1); } else if (diff < 0 && state.carouselIndex > 0) { goToSlide(state.carouselIndex - 1); } else { goToSlide(state.carouselIndex); } } else { goToSlide(state.carouselIndex); } }); // Auto-advance setInterval(() => { if (!state.isCarouselPaused) { const nextIndex = (state.carouselIndex + 1) % slideCount; goToSlide(nextIndex); } }, 4000); } function goToSlide(index) { state.carouselIndex = index; carouselTrack.style.transform = `translateX(-${index * 100}%)`; const indicators = carouselIndicators.children; for (let i = 0; i < indicators.length; i++) { indicators[i].classList.toggle('active', i === index); } } // Address Copy function initAddressCopy() { const fullAddress = 'UQARxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxbn5l'; copyAddressBtn.addEventListener('click', async () => { try { await navigator.clipboard.writeText(fullAddress); showFeedback(addressFeedback); } catch (err) { // Fallback const textarea = document.createElement('textarea'); textarea.value = fullAddress; document.body.appendChild(textarea); textarea.select(); document.execCommand('copy'); document.body.removeChild(textarea); showFeedback(addressFeedback); } }); } function showFeedback(element) { element.classList.add('show'); setTimeout(() => { element.classList.remove('show'); }, 1500); } // Transfer Form function initTransferForm() { const form = document.getElementById('transferForm'); const recipientInput = document.getElementById('recipientInput'); const amountInput = document.getElementById('amountInput'); // Limit input to balance amountInput.addEventListener('input', (e) => { const value = parseFloat(e.target.value); if (value > state.balance) { e.target.value = state.balance.toFixed(2); } }); form.addEventListener('submit', (e) => { e.preventDefault(); const recipient = recipientInput.value.trim(); const amount = parseFloat(amountInput.value); if (!recipient || isNaN(amount) || amount <= 0) { showToast('Please fill all fields', 'error'); return; } if (amount > state.balance) { showToast('Insufficient balance', 'error'); return; } // Simulate transfer const btn = form.querySelector('.btn-primary'); btn.disabled = true; btn.innerHTML = 'Processing...'; setTimeout(() => { state.balance -= amount; document.querySelector('.balance-main').textContent = state.balance.toFixed(2) + '₽'; showToast(`Sent ${amount.toFixed(2)}₽`, 'success'); renderTab('transfer'); }, 1500); }); } // Store Actions function handleSubscribe(level, price) { if (price > state.balance) { showToast('Insufficient balance', 'error'); return; } showToast(`Subscribed to ${level}!`, 'success'); state.balance -= price; document.querySelector('.balance-main').textContent = state.balance.toFixed(2) + '₽'; } function handleRenew(level, price) { if (price > state.balance) { showToast('Insufficient balance', 'error'); return; } showToast(`${level} renewed!`, 'success'); state.balance -= price; document.querySelector('.balance-main').textContent = state.balance.toFixed(2) + '₽'; } // Task Actions function generateLink() { const btn = document.getElementById('createLinkBtn'); const field = document.getElementById('linkField'); btn.style.display = 'none'; field.classList.add('show'); setTimeout(() => copyToClipboard('vk.com/uwu.chan', field), 100); } function generateCode() { const btn = document.getElementById('genCodeBtn'); const field = document.getElementById('codeField'); btn.style.display = 'none'; field.classList.add('show'); setTimeout(() => copyToClipboard('YUfs1if421Hf', field), 100); } async function copyToClipboard(text, element) { try { await navigator.clipboard.writeText(text); const originalBg = element.style.background; element.style.background = 'var(--success)'; element.style.color = 'white'; setTimeout(() => { element.style.background = originalBg; element.style.color = ''; }, 300); showToast('Copied!', 'success'); } catch (err) { showToast('Copied!', 'success'); } } function completeTask(channel, reward) { setTimeout(() => { showToast(`+${reward}₽ for ${channel}`, 'success'); state.balance += reward; document.querySelector('.balance-main').textContent = state.balance.toFixed(2) + '₽'; }, 500); } // Toast Notification function showToast(message, type = 'success') { let toast = document.getElementById('appToast'); if (!toast) { toast = document.createElement('div'); toast.id = 'appToast'; toast.className = 'toast'; document.body.appendChild(toast); } toast.textContent = message; toast.className = `toast ${type} show`; setTimeout(() => { toast.classList.remove('show'); }, 2000); } // Start the app document.addEventListener('DOMContentLoaded', init); // Prevent bounce on iOS document.addEventListener('touchmove', (e) => { if (e.target.closest('.info-block')) return; e.preventDefault(); }, { passive: false });