coerxso's picture
Upload 73 files
3e8a166 verified
raw
history blame
6.35 kB
// management/static/js/main.js
// -*- coding: utf-8 -*-
// VAPID_PUBLIC_KEY will be passed from the Django template.
// This is a placeholder; it will be filled with the correct value in the HTML file.
const VAPID_PUBLIC_KEY_PLACEHOLDER = "{{ vapid_public_key }}";
/**
* Converts a base64 string to a Uint8Array.
* @param {string} base64String
* @returns {Uint8Array}
*/
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
/**
* Registers the service worker for the PWA.
* @returns {Promise<ServiceWorkerRegistration|null>}
*/
async function registerServiceWorker() {
if ('serviceWorker' in navigator) {
try {
const registration = await navigator.serviceWorker.register('/service-worker.js');
console.log('Service worker registered successfully.');
return registration;
} catch (error) {
console.error('Service worker registration failed:', error);
return null;
}
}
console.error('Service workers are not supported in this browser.');
return null;
}
/**
* Subscribes the user to push notifications.
* @param {ServiceWorkerRegistration} registration
*/
async function subscribeUserToPush(registration) {
if (!('PushManager' in window)) {
console.error('Push notifications are not supported.');
return;
}
if (!VAPID_PUBLIC_KEY_PLACEHOLDER || VAPID_PUBLIC_KEY_PLACEHOLDER === "YOUR_VAPID_PUBLIC_KEY_HERE") {
console.error("VAPID public key not configured.");
return;
}
try {
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY_PLACEHOLDER)
});
console.log('User is subscribed to push.');
const response = await fetch('/api/push/subscribe/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value
},
body: JSON.stringify(subscription)
});
if (!response.ok) {
console.error('Failed to save push subscription on server.');
}
} catch (error) {
console.error('Push subscription failed:', error);
}
}
/**
* Fetches and displays user dashboard data from the API.
*/
async function fetchDashboardData() {
try {
const response = await fetch('/api/dashboard/');
if (!response.ok) {
throw new Error('Network response was not ok');
}
const data = await response.json();
document.getElementById('username-display').textContent = data.username;
document.getElementById('service-status').textContent = data.service_status;
document.getElementById('used-traffic').textContent = (data.used_traffic / (1024 ** 3)).toFixed(2) + ' GB';
document.getElementById('total-traffic').textContent = (data.total_traffic / (1024 ** 3)).toFixed(2) + ' GB';
const configsList = document.getElementById('configs-list');
configsList.innerHTML = ''; // Clear previous content
data.configs.forEach(config => {
const listItem = document.createElement('li');
listItem.className = 'bg-gray-50 rounded-md p-3 border border-gray-200';
listItem.innerHTML = `
<div class="font-bold text-gray-800">${config.remark}</div>
<div class="text-sm text-gray-500 break-all">${config.link}</div>
`;
configsList.appendChild(listItem);
});
} catch (error) {
console.error('Error fetching dashboard data:', error);
document.body.innerHTML = '<p class="text-red-500 text-center">خطا در بارگذاری اطلاعات داشبورد.</p>';
}
}
/**
* Handles the generation of the Telegram security token.
*/
async function handleTelegramTokenGeneration() {
const generateTokenBtn = document.getElementById('generate-token-btn');
const tokenDisplayArea = document.getElementById('token-display-area');
const telegramTokenCode = document.getElementById('telegram-token');
if (!generateTokenBtn) return;
generateTokenBtn.addEventListener('click', async () => {
const response = await fetch('/api/telegram/generate-token/', {
method: 'POST',
headers: {
'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value
}
});
if (response.ok) {
const data = await response.json();
telegramTokenCode.textContent = data.token;
tokenDisplayArea.classList.remove('hidden');
} else {
// Using a custom modal or message box instead of alert()
console.error('Failed to generate token.');
alert('خطا در تولید توکن.');
}
});
}
document.addEventListener('DOMContentLoaded', async () => {
// Fetch and render dashboard data
await fetchDashboardData();
// PWA and Push Notification logic
const registration = await registerServiceWorker();
if (registration) {
if (Notification.permission === 'granted') {
console.log('Push permission already granted.');
} else if (Notification.permission === 'denied') {
console.log('Push permission denied by user.');
} else {
// Prompt the user for permission
// This is a browser feature, so we don't need a custom modal
Notification.requestPermission().then(permission => {
if (permission === 'granted') {
subscribeUserToPush(registration);
} else {
console.log('User denied push notification permission.');
}
});
}
}
// Telegram token generation
handleTelegramTokenGeneration();
});