help@rskworld.in +91 93305 39277
RSK World
  • Home
  • Development
    • Web Development
    • Mobile Apps
    • Software
    • Games
    • Project
  • Technologies
    • Data Science
    • AI Development
    • Cloud Development
    • Blockchain
    • Cyber Security
    • Dev Tools
    • Testing Tools
  • About
  • Contact

Theme Settings

Color Scheme
Display Options
Font Size
100%
Back to Project
RSK World
rust-web-server
/
static
/
js
RSK World
rust-web-server
Rust Web Server - High-Performance Async Web Server + WebSocket Support + JWT Authentication + File Upload + Memory Safety + Educational Design
js
  • app.js26.6 KB
application_mailer.rbapp.js
static/js/app.js
Raw Download
Find: Go to:
/*
 * JavaScript Application - Rust Web Server
 * 
 * Created by RSK World (https://rskworld.in)
 * Founder: Molla Samser
 * Designer & Tester: Rima Khatun
 * 
 * Contact:
 * - Email: hello@rskworld.in, support@rskworld.in
 * - Phone: +91 93305 39277
 * - Address: Nutanhat, Mongolkote, Purba Burdwan, West Bengal, India, 713147
 * 
 * © 2026 RSK World. All rights reserved.
 * Content used for educational purposes only.
 */

// Global variables
let serverStats = {
    uptime: 0,
    requests: 0,
    connections: 0,
    memory: 0
};

let updateInterval;

// Initialize application
document.addEventListener('DOMContentLoaded', function() {
    initializeApp();
});

function initializeApp() {
    console.log('🦀 Rust Web Server - Frontend initialized');
    
    // Hide loading screen after a short delay
    setTimeout(() => {
        hideLoadingScreen();
    }, 2000);
    
    // Start updating stats
    updateServerStats();
    updateInterval = setInterval(updateServerStats, 5000);
    
    // Setup event listeners
    setupEventListeners();
    
    // Setup smooth scrolling
    setupSmoothScrolling();
    
    // Setup interactive elements
    setupInteractiveElements();
    
    // Initialize API testing functionality
    setupApiTesting();
}

// Hide loading screen
function hideLoadingScreen() {
    const loadingScreen = document.getElementById('loading-screen');
    if (loadingScreen) {
        loadingScreen.style.opacity = '0';
        setTimeout(() => {
            loadingScreen.style.display = 'none';
        }, 500);
    }
}

// Show loading screen (for manual control)
function showLoadingScreen() {
    const loadingScreen = document.getElementById('loading-screen');
    if (loadingScreen) {
        loadingScreen.style.display = 'flex';
        loadingScreen.style.opacity = '1';
    }
}

// Update server statistics
async function updateServerStats() {
    try {
        const response = await fetch('/api/stats');
        
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        const stats = await response.json();
        
        // Update global stats
        serverStats = {
            uptime: stats.uptime_seconds || 0,
            requests: stats.request_count || 0,
            connections: stats.active_connections || 0,
            memory: stats.memory_usage_mb || 0
        };
        
        // Update UI
        updateStatsUI();
        
    } catch (error) {
        console.error('Failed to fetch server stats:', error);
        showNotification('Failed to fetch server statistics', 'warning');
    }
}

// Update statistics UI
function updateStatsUI() {
    const elements = {
        uptime: document.getElementById('uptime'),
        requests: document.getElementById('requests'),
        connections: document.getElementById('connections'),
        memory: document.getElementById('memory')
    };
    
    // Update values with animation
    animateValue(elements.uptime, serverStats.uptime);
    animateValue(elements.requests, serverStats.requests);
    animateValue(elements.connections, serverStats.connections);
    animateValue(elements.memory, serverStats.memory, true);
    
    // Update uptime display
    if (elements.uptime) {
        elements.uptime.textContent = formatUptime(serverStats.uptime);
    }
}

// Animate numeric values
function animateValue(element, value, isFloat = false) {
    if (!element) return;
    
    const current = parseFloat(element.textContent) || 0;
    const target = value;
    const duration = 1000;
    const steps = 30;
    const increment = (target - current) / steps;
    let step = 0;
    
    const timer = setInterval(() => {
        step++;
        const newValue = current + (increment * step);
        
        if (isFloat) {
            element.textContent = newValue.toFixed(1);
        } else {
            element.textContent = Math.round(newValue);
        }
        
        if (step >= steps) {
            clearInterval(timer);
            if (isFloat) {
                element.textContent = target.toFixed(1);
            } else {
                element.textContent = target;
            }
        }
    }, duration / steps);
}

// Format uptime in human readable format
function formatUptime(seconds) {
    const days = Math.floor(seconds / 86400);
    const hours = Math.floor((seconds % 86400) / 3600);
    const minutes = Math.floor((seconds % 3600) / 60);
    const secs = seconds % 60;
    
    if (days > 0) {
        return `${days}d ${hours}h ${minutes}m`;
    } else if (hours > 0) {
        return `${hours}h ${minutes}m ${secs}s`;
    } else if (minutes > 0) {
        return `${minutes}m ${secs}s`;
    } else {
        return `${secs}s`;
    }
}

// Setup event listeners
function setupEventListeners() {
    // Navigation links
    document.querySelectorAll('.nav-link').forEach(link => {
        link.addEventListener('click', function(e) {
            e.preventDefault();
            const target = this.getAttribute('href');
            if (target.startsWith('#')) {
                scrollToSection(target.substring(1));
            }
        });
    });
    
    // Feature cards
    document.querySelectorAll('.feature-card').forEach(card => {
        card.addEventListener('click', function() {
            this.style.transform = 'scale(0.95)';
            setTimeout(() => {
                this.style.transform = '';
            }, 150);
        });
    });
    
    // API endpoint cards
    document.querySelectorAll('.endpoint').forEach(endpoint => {
        endpoint.addEventListener('click', function() {
            const method = this.querySelector('.endpoint-method').textContent;
            const path = this.querySelector('.endpoint-path').textContent;
            testApiEndpoint(method, path);
        });
    });
}

// Setup smooth scrolling
function setupSmoothScrolling() {
    document.querySelectorAll('a[href^="#"]').forEach(anchor => {
        anchor.addEventListener('click', function(e) {
            e.preventDefault();
            const target = document.querySelector(this.getAttribute('href'));
            if (target) {
                target.scrollIntoView({
                    behavior: 'smooth',
                    block: 'start'
                });
            }
        });
    });
}

// Setup interactive elements
function setupInteractiveElements() {
    // Add hover effects to buttons
    document.querySelectorAll('.btn').forEach(btn => {
        btn.addEventListener('mouseenter', function() {
            this.style.transform = 'translateY(-2px)';
        });
        
        btn.addEventListener('mouseleave', function() {
            this.style.transform = '';
        });
    });
    
    // Add ripple effect to buttons
    document.querySelectorAll('.btn').forEach(btn => {
        btn.addEventListener('click', function(e) {
            const ripple = document.createElement('span');
            ripple.classList.add('ripple');
            this.appendChild(ripple);
            
            const rect = this.getBoundingClientRect();
            const size = Math.max(rect.width, rect.height);
            const x = e.clientX - rect.left - size / 2;
            const y = e.clientY - rect.top - size / 2;
            
            ripple.style.width = ripple.style.height = size + 'px';
            ripple.style.left = x + 'px';
            ripple.style.top = y + 'px';
            
            setTimeout(() => {
                ripple.remove();
            }, 600);
        });
    });
}

// Setup API testing functionality
function setupApiTesting() {
    // Add test buttons to API endpoints
    document.querySelectorAll('.endpoint').forEach(endpoint => {
        const testBtn = document.createElement('button');
        testBtn.textContent = 'Test';
        testBtn.className = 'btn btn-sm btn-secondary';
        testBtn.style.marginLeft = '10px';
        testBtn.style.fontSize = '0.8rem';
        testBtn.style.padding = '0.25rem 0.5rem';
        
        testBtn.addEventListener('click', function(e) {
            e.stopPropagation();
            const method = endpoint.querySelector('.endpoint-method').textContent;
            const path = endpoint.querySelector('.endpoint-path').textContent;
            testApiEndpoint(method, path);
        });
        
        endpoint.querySelector('.endpoint-description').appendChild(testBtn);
    });
}

// Test API endpoint
async function testApiEndpoint(method, path) {
    try {
        showNotification(`Testing ${method} ${path}...`, 'info');
        
        let response;
        const startTime = Date.now();
        
        if (method === 'GET') {
            response = await fetch(path);
        } else if (method === 'POST') {
            response = await fetch(path, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    message: 'Test message from frontend',
                    timestamp: new Date().toISOString()
                })
            });
        }
        
        const endTime = Date.now();
        const responseTime = endTime - startTime;
        
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        const data = await response.json();
        
        // Show results in a modal
        showApiResults(method, path, response, responseTime, data);
        
    } catch (error) {
        console.error('API test failed:', error);
        showNotification(`API test failed: ${error.message}`, 'danger');
    }
}

// Show API results
function showApiResults(method, path, response, responseTime, data) {
    const modal = document.createElement('div');
    modal.className = 'modal';
    modal.innerHTML = `
        <div class="modal-content">
            <div class="modal-header">
                <h3>API Test Results</h3>
                <button class="modal-close">&times;</button>
            </div>
            <div class="modal-body">
                <div class="test-info">
                    <p><strong>Method:</strong> ${method}</p>
                    <p><strong>Path:</strong> ${path}</p>
                    <p><strong>Status:</strong> <span class="status-${response.ok ? 'success' : 'error'}">${response.status}</span></p>
                    <p><strong>Response Time:</strong> ${responseTime}ms</p>
                </div>
                <div class="test-response">
                    <h4>Response:</h4>
                    <pre class="code-block">${JSON.stringify(data, null, 2)}</pre>
                </div>
            </div>
        </div>
    `;
    
    // Add modal styles if not already present
    if (!document.querySelector('#modal-styles')) {
        const style = document.createElement('style');
        style.id = 'modal-styles';
        style.textContent = `
            .modal {
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: rgba(0, 0, 0, 0.5);
                display: flex;
                justify-content: center;
                align-items: center;
                z-index: 1000;
            }
            .modal-content {
                background: white;
                border-radius: 10px;
                max-width: 600px;
                max-height: 80vh;
                overflow-y: auto;
                box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
            }
            .modal-header {
                padding: 1.5rem;
                border-bottom: 1px solid #eee;
                display: flex;
                justify-content: space-between;
                align-items: center;
            }
            .modal-header h3 {
                margin: 0;
            }
            .modal-close {
                background: none;
                border: none;
                font-size: 1.5rem;
                cursor: pointer;
                color: #666;
            }
            .modal-body {
                padding: 1.5rem;
            }
            .test-info {
                margin-bottom: 1.5rem;
            }
            .test-info p {
                margin: 0.5rem 0;
            }
            .status-success {
                color: #28a745;
                font-weight: bold;
            }
            .status-error {
                color: #dc3545;
                font-weight: bold;
            }
        `;
        document.head.appendChild(style);
    }
    
    document.body.appendChild(modal);
    
    // Close modal handlers
    const closeBtn = modal.querySelector('.modal-close');
    closeBtn.addEventListener('click', () => {
        modal.remove();
    });
    
    modal.addEventListener('click', (e) => {
        if (e.target === modal) {
            modal.remove();
        }
    });
}

// Show notification
function showNotification(message, type = 'info') {
    const notification = document.createElement('div');
    notification.className = `alert alert-${type} notification`;
    notification.textContent = message;
    notification.style.position = 'fixed';
    notification.style.top = '20px';
    notification.style.right = '20px';
    notification.style.zIndex = '1001';
    notification.style.maxWidth = '300px';
    
    document.body.appendChild(notification);
    
    // Auto remove after 5 seconds
    setTimeout(() => {
        notification.style.opacity = '0';
        notification.style.transform = 'translateX(100%)';
        notification.style.transition = 'all 0.3s ease';
        setTimeout(() => {
            notification.remove();
        }, 300);
    }, 5000);
}

// Setup event listeners
function setupEventListeners() {
    // Mobile navigation toggle
    const navToggle = document.getElementById('nav-toggle');
    const navMenu = document.getElementById('nav-menu');
    
    if (navToggle && navMenu) {
        navToggle.addEventListener('click', () => {
            navMenu.classList.toggle('active');
        });
    }
    
    // Close mobile menu when clicking on a link
    const navLinks = document.querySelectorAll('.nav-link');
    navLinks.forEach(link => {
        link.addEventListener('click', () => {
            if (navMenu) {
                navMenu.classList.remove('active');
            }
        });
    });
    
    // Update active navigation on scroll
    window.addEventListener('scroll', updateActiveNavigation);
}

// Setup smooth scrolling
function setupSmoothScrolling() {
    const links = document.querySelectorAll('a[href^="#"]');
    links.forEach(link => {
        link.addEventListener('click', (e) => {
            e.preventDefault();
            const targetId = link.getAttribute('href').substring(1);
            const targetElement = document.getElementById(targetId);
            
            if (targetElement) {
                const offsetTop = targetElement.offsetTop - 70; // Account for fixed navbar
                window.scrollTo({
                    top: offsetTop,
                    behavior: 'smooth'
                });
            }
        });
    });
}

// Setup interactive elements
function setupInteractiveElements() {
    // Animate stats on scroll
    const observerOptions = {
        threshold: 0.5,
        rootMargin: '0px'
    };
    
    const observer = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                animateStats();
                observer.unobserve(entry.target);
            }
        });
    }, observerOptions);
    
    const heroStats = document.querySelector('.hero-stats');
    if (heroStats) {
        observer.observe(heroStats);
    }
    
    // Setup file upload area
    setupFileUpload();
    
    // Setup WebSocket chat
    setupWebSocket();
}

// Update active navigation based on scroll position
function updateActiveNavigation() {
    const sections = document.querySelectorAll('section[id]');
    const navLinks = document.querySelectorAll('.nav-link');
    
    let currentSection = '';
    sections.forEach(section => {
        const sectionTop = section.offsetTop - 100;
        const sectionHeight = section.offsetHeight;
        
        if (window.pageYOffset >= sectionTop && 
            window.pageYOffset < sectionTop + sectionHeight) {
            currentSection = section.getAttribute('id');
        }
    });
    
    navLinks.forEach(link => {
        link.classList.remove('active');
        if (link.getAttribute('href') === `#${currentSection}`) {
            link.classList.add('active');
        }
    });
}

// Animate statistics
function animateStats() {
    const statNumbers = document.querySelectorAll('.stat-number');
    
    statNumbers.forEach(stat => {
        const target = parseInt(stat.getAttribute('data-target'));
        const duration = 2000;
        const increment = target / (duration / 16);
        let current = 0;
        
        const updateNumber = () => {
            current += increment;
            if (current < target) {
                stat.textContent = Math.floor(current);
                requestAnimationFrame(updateNumber);
            } else {
                stat.textContent = target;
            }
        };
        
        updateNumber();
    });
}

// Scroll to specific section
function scrollToSection(sectionId) {
    const section = document.getElementById(sectionId);
    if (section) {
        const offsetTop = section.offsetTop - 70;
        window.scrollTo({
            top: offsetTop,
            behavior: 'smooth'
        });
    }
}

// Open API tester modal
function openApiTester() {
    showModal('API Tester', `
        <div class="api-tester">
            <div class="form-group">
                <label>Method:</label>
                <select id="api-method">
                    <option value="GET">GET</option>
                    <option value="POST">POST</option>
                    <option value="PUT">PUT</option>
                    <option value="DELETE">DELETE</option>
                </select>
            </div>
            <div class="form-group">
                <label>Endpoint:</label>
                <input type="text" id="api-endpoint" placeholder="/api/stats" value="/api/stats">
            </div>
            <div class="form-group">
                <label>Request Body (JSON):</label>
                <textarea id="api-body" rows="5" placeholder='{"message": "Hello, World!"}'></textarea>
            </div>
            <button class="btn btn-primary" onclick="testApiCall()">Send Request</button>
            <div id="api-response" class="api-response"></div>
        </div>
    `);
}

// Test API call
async function testApiCall() {
    const method = document.getElementById('api-method').value;
    const endpoint = document.getElementById('api-endpoint').value;
    const body = document.getElementById('api-body').value;
    const responseDiv = document.getElementById('api-response');
    
    try {
        const options = {
            method: method,
            headers: {
                'Content-Type': 'application/json',
            }
        };
        
        if (method !== 'GET' && body) {
            options.body = body;
        }
        
        const response = await fetch(endpoint, options);
        const data = await response.json();
        
        responseDiv.innerHTML = `
            <h4>Response (${response.status}):</h4>
            <pre>${JSON.stringify(data, null, 2)}</pre>
        `;
        
    } catch (error) {
        responseDiv.innerHTML = `
            <h4>Error:</h4>
            <p>${error.message}</p>
        `;
    }
}

// Setup file upload
function setupFileUpload() {
    const uploadArea = document.getElementById('upload-area');
    const fileInput = document.getElementById('file-input');
    
    if (!uploadArea || !fileInput) return;
    
    // Click to upload
    uploadArea.addEventListener('click', () => {
        fileInput.click();
    });
    
    // Drag and drop
    uploadArea.addEventListener('dragover', (e) => {
        e.preventDefault();
        uploadArea.classList.add('dragover');
    });
    
    uploadArea.addEventListener('dragleave', () => {
        uploadArea.classList.remove('dragover');
    });
    
    uploadArea.addEventListener('drop', (e) => {
        e.preventDefault();
        uploadArea.classList.remove('dragover');
        handleFiles(e.dataTransfer.files);
    });
    
    // File input change
    fileInput.addEventListener('change', (e) => {
        handleFiles(e.target.files);
    });
}

// Handle file upload
async function handleFiles(files) {
    if (files.length === 0) return;
    
    const formData = new FormData();
    for (let i = 0; i < files.length; i++) {
        formData.append('files', files[i]);
    }
    
    try {
        const response = await fetch('/api/upload', {
            method: 'POST',
            body: formData
        });
        
        const result = await response.json();
        
        if (result.success) {
            showNotification(`Successfully uploaded ${result.files.length} files`, 'success');
            updateFileList(result.files);
        } else {
            showNotification('Upload failed: ' + result.message, 'error');
        }
        
    } catch (error) {
        showNotification('Upload error: ' + error.message, 'error');
    }
}

// Update file list
function updateFileList(files) {
    const fileList = document.getElementById('file-list');
    if (!fileList) return;
    
    fileList.innerHTML = '';
    
    files.forEach(file => {
        const fileItem = document.createElement('div');
        fileItem.className = 'file-item';
        fileItem.innerHTML = `
            <div class="file-info">
                <strong>${file.original_name}</strong>
                <span class="file-size">${formatBytes(file.size)}</span>
            </div>
            <button class="btn btn-sm btn-danger" onclick="deleteFile('${file.id}')">
                <i class="fas fa-trash"></i>
            </button>
        `;
        fileList.appendChild(fileItem);
    });
}

// Setup WebSocket
function setupWebSocket() {
    const wsStatus = document.getElementById('ws-status');
    const chatInput = document.getElementById('chat-input');
    const sendBtn = document.getElementById('send-btn');
    
    if (!wsStatus || !chatInput || !sendBtn) return;
    
    let ws;
    
    function connectWebSocket() {
        const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
        const wsUrl = `${protocol}//${window.location.host}/ws`;
        
        ws = new WebSocket(wsUrl);
        
        ws.onopen = () => {
            updateConnectionStatus(true);
            chatInput.disabled = false;
            sendBtn.disabled = false;
        };
        
        ws.onclose = () => {
            updateConnectionStatus(false);
            chatInput.disabled = true;
            sendBtn.disabled = true;
            
            // Try to reconnect after 3 seconds
            setTimeout(connectWebSocket, 3000);
        };
        
        ws.onmessage = (event) => {
            const message = JSON.parse(event.data);
            displayChatMessage(message);
        };
        
        ws.onerror = (error) => {
            console.error('WebSocket error:', error);
        };
    }
    
    function updateConnectionStatus(connected) {
        const statusDot = wsStatus.querySelector('.status-dot');
        const statusText = wsStatus.querySelector('.status-text');
        
        if (connected) {
            statusDot.classList.remove('offline');
            statusDot.classList.add('online');
            statusText.textContent = 'Connected';
        } else {
            statusDot.classList.remove('online');
            statusDot.classList.add('offline');
            statusText.textContent = 'Disconnected';
        }
    }
    
    // Send message
    sendBtn.addEventListener('click', sendMessage);
    chatInput.addEventListener('keypress', (e) => {
        if (e.key === 'Enter') {
            sendMessage();
        }
    });
    
    function sendMessage() {
        const message = chatInput.value.trim();
        if (message && ws && ws.readyState === WebSocket.OPEN) {
            ws.send(JSON.stringify({
                type: 'chat',
                message: message,
                user: 'User'
            }));
            chatInput.value = '';
        }
    }
    
    // Start connection
    connectWebSocket();
}

// Display chat message
function displayChatMessage(message) {
    const chatMessages = document.getElementById('chat-messages');
    if (!chatMessages) return;
    
    const messageDiv = document.createElement('div');
    messageDiv.className = 'chat-message';
    messageDiv.innerHTML = `
        <strong>${message.user}:</strong> ${message.message}
        <span class="message-time">${new Date().toLocaleTimeString()}</span>
    `;
    
    chatMessages.appendChild(messageDiv);
    chatMessages.scrollTop = chatMessages.scrollHeight;
}

// Format bytes
function formatBytes(bytes) {
    if (bytes === 0) return '0 Bytes';
    const k = 1024;
    const sizes = ['Bytes', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

// Scroll to section
function scrollToSection(sectionId) {
    const section = document.getElementById(sectionId);
    if (section) {
        section.scrollIntoView({
            behavior: 'smooth',
            block: 'start'
        });
    }
}

// Utility functions
function formatBytes(bytes) {
    const units = ['B', 'KB', 'MB', 'GB', 'TB'];
    let size = bytes;
    let unitIndex = 0;
    
    while (size >= 1024 && unitIndex < units.length - 1) {
        size /= 1024;
        unitIndex++;
    }
    
    return `${size.toFixed(1)} ${units[unitIndex]}`;
}

function formatNumber(num) {
    return num.toLocaleString();
}

// Cleanup on page unload
window.addEventListener('beforeunload', () => {
    if (updateInterval) {
        clearInterval(updateInterval);
    }
});

// Export functions for external use
window.RustWebServer = {
    updateServerStats,
    testApiEndpoint,
    showNotification,
    formatBytes,
    formatNumber
};
883 lines•26.6 KB
javascript

About RSK World

Founded by Molla Samser, with Designer & Tester Rima Khatun, RSK World is your one-stop destination for free programming resources, source code, and development tools.

Founder: Molla Samser
Designer & Tester: Rima Khatun

Development

  • Game Development
  • Web Development
  • Mobile Development
  • AI Development
  • Development Tools

Legal

  • Terms & Conditions
  • Privacy Policy
  • Disclaimer

Contact Info

Nutanhat, Mongolkote
Purba Burdwan, West Bengal
India, 713147

+91 93305 39277

hello@rskworld.in
support@rskworld.in

© 2026 RSK World. All rights reserved.

Content used for educational purposes only. View Disclaimer