// 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
Available Subscriptions
`,
history: `
Subscription
Yesterday, 09:15
-250.00₽
Transfer Out
Dec 24, 18:45
-150.00₽
Task Reward
Dec 22, 11:20
+100.00₽
`,
tasks: `
Available Tasks
`
};
// 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 });