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
code-assistant-bot
/
static
/
js
RSK World
code-assistant-bot
Code Assistant Bot - Python + Flask + OpenAI API + Code Generation + Debugging + Code Analysis + GitHub Integration
js
  • app.js34.1 KB
app.js
static/js/app.js
Raw Download
Find: Go to:
/**
 * Code Assistant Bot - Frontend JavaScript
 * Author: RSK World (https://rskworld.in)
 * Founder: Molla Samser
 * Designer & Tester: Rima Khatun
 * Contact: help@rskworld.in, +91 93305 39277
 * Year: 2026
 */

class CodeAssistantBot {
    constructor() {
        this.initializeElements();
        this.bindEvents();
        this.initializeTooltips();
        this.currentAction = 'generate';
        this.currentLanguage = 'python';
    }

    initializeElements() {
        // Input elements
        this.actionSelect = document.getElementById('actionSelect');
        this.languageSelect = document.getElementById('languageSelect');
        this.codeInput = document.getElementById('codeInput');
        this.errorMessage = document.getElementById('errorMessage');
        this.errorMessageContainer = document.getElementById('errorMessageContainer');
        this.codeInputLabel = document.getElementById('codeInputLabel');
        this.charCount = document.getElementById('charCount');
        
        // New advanced elements
        this.targetLanguageSelect = document.getElementById('targetLanguageSelect');
        this.conversionOptionsContainer = document.getElementById('conversionOptionsContainer');
        this.testTypeSelect = document.getElementById('testTypeSelect');
        this.testingOptionsContainer = document.getElementById('testingOptionsContainer');
        this.optimizationOptionsContainer = document.getElementById('optimizationOptionsContainer');
        this.code2Input = document.getElementById('code2Input');
        this.comparisonOptionsContainer = document.getElementById('comparisonOptionsContainer');
        this.formatStyleSelect = document.getElementById('formatStyleSelect');
        this.formattingOptionsContainer = document.getElementById('formattingOptionsContainer');
        this.docStyleSelect = document.getElementById('docStyleSelect');
        this.documentationOptionsContainer = document.getElementById('documentationOptionsContainer');
        
        // Buttons
        this.processBtn = document.getElementById('processBtn');
        this.processBtnText = document.getElementById('processBtnText');
        this.clearBtn = document.getElementById('clearBtn');
        this.copyBtn = document.getElementById('copyBtn');
        this.downloadBtn = document.getElementById('downloadBtn');
        
        // Output elements
        this.loadingIndicator = document.getElementById('loadingIndicator');
        this.outputContainer = document.getElementById('outputContainer');
        this.outputContent = document.getElementById('outputContent');
        this.outputCode = document.getElementById('outputCode');
        this.outputMetadata = document.getElementById('outputMetadata');
        this.errorContainer = document.getElementById('errorContainer');
        this.errorMessageDisplay = document.getElementById('errorMessageDisplay');
        this.welcomeMessage = document.getElementById('welcomeMessage');
        
        // GitHub elements
        this.githubSearchInput = document.getElementById('githubSearchInput');
        this.githubLanguageFilter = document.getElementById('githubLanguageFilter');
        this.githubSearchBtn = document.getElementById('githubSearchBtn');
        this.clearGithubBtn = document.getElementById('clearGithubBtn');
        this.githubResults = document.getElementById('githubResults');
        this.githubResultsContainer = document.getElementById('githubResultsContainer');
        
        // Toast
        this.toast = new bootstrap.Toast(document.getElementById('notificationToast'));
        this.toastMessage = document.getElementById('toastMessage');
    }

    bindEvents() {
        // Action selection
        this.actionSelect.addEventListener('change', () => this.handleActionChange());
        
        // Language selection
        this.languageSelect.addEventListener('change', () => this.handleLanguageChange());
        
        // Code input
        this.codeInput.addEventListener('input', () => this.updateCharCount());
        
        // Process button
        this.processBtn.addEventListener('click', () => this.processRequest());
        
        // Clear button
        this.clearBtn.addEventListener('click', () => this.clearInput());
        
        // Copy button
        this.copyBtn.addEventListener('click', () => this.copyToClipboard());
        
        // Download button
        this.downloadBtn.addEventListener('click', () => this.downloadCode());
        
        // GitHub search
        this.githubSearchBtn.addEventListener('click', () => this.searchGitHub());
        this.clearGithubBtn.addEventListener('click', () => this.clearGitHubResults());
        
        // Enter key for GitHub search
        this.githubSearchInput.addEventListener('keypress', (e) => {
            if (e.key === 'Enter') {
                this.searchGitHub();
            }
        });
        
        // Ctrl+Enter for processing
        this.codeInput.addEventListener('keydown', (e) => {
            if (e.ctrlKey && e.key === 'Enter') {
                e.preventDefault();
                this.processRequest();
            }
        });
    }

    initializeTooltips() {
        // Initialize Bootstrap tooltips if needed
        const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
        tooltipTriggerList.map(function (tooltipTriggerEl) {
            return new bootstrap.Tooltip(tooltipTriggerEl);
        });
    }

    handleActionChange() {
        this.currentAction = this.actionSelect.value;
        
        // Hide all option containers first
        this.errorMessageContainer.style.display = 'none';
        this.conversionOptionsContainer.style.display = 'none';
        this.testingOptionsContainer.style.display = 'none';
        this.optimizationOptionsContainer.style.display = 'none';
        this.comparisonOptionsContainer.style.display = 'none';
        this.formattingOptionsContainer.style.display = 'none';
        this.documentationOptionsContainer.style.display = 'none';
        
        // Update UI based on selected action
        switch (this.currentAction) {
            case 'generate':
                this.codeInputLabel.textContent = 'Prompt:';
                this.codeInput.placeholder = 'Describe code you want to generate...';
                this.processBtnText.textContent = 'Generate Code';
                break;
            case 'debug':
                this.codeInputLabel.textContent = 'Code to Debug:';
                this.codeInput.placeholder = 'Paste your code here...';
                this.processBtnText.textContent = 'Debug Code';
                this.errorMessageContainer.style.display = 'block';
                break;
            case 'explain':
                this.codeInputLabel.textContent = 'Code to Explain:';
                this.codeInput.placeholder = 'Paste your code here...';
                this.processBtnText.textContent = 'Explain Code';
                break;
            case 'syntax':
                this.codeInputLabel.textContent = 'Code to Check:';
                this.codeInput.placeholder = 'Paste your code here...';
                this.processBtnText.textContent = 'Check Syntax';
                break;
            case 'analyze':
                this.codeInputLabel.textContent = 'Code to Analyze:';
                this.codeInput.placeholder = 'Paste your code here...';
                this.processBtnText.textContent = 'Analyze Code';
                break;
            case 'optimize':
                this.codeInputLabel.textContent = 'Code to Optimize:';
                this.codeInput.placeholder = 'Paste your code here...';
                this.processBtnText.textContent = 'Optimize Code';
                this.optimizationOptionsContainer.style.display = 'block';
                break;
            case 'convert':
                this.codeInputLabel.textContent = 'Code to Convert:';
                this.codeInput.placeholder = 'Paste your code here...';
                this.processBtnText.textContent = 'Convert Code';
                this.conversionOptionsContainer.style.display = 'block';
                break;
            case 'test':
                this.codeInputLabel.textContent = 'Code to Test:';
                this.codeInput.placeholder = 'Paste your code here...';
                this.processBtnText.textContent = 'Test Code';
                this.testingOptionsContainer.style.display = 'block';
                break;
            case 'format':
                this.codeInputLabel.textContent = 'Code to Format:';
                this.codeInput.placeholder = 'Paste your code here...';
                this.processBtnText.textContent = 'Format Code';
                this.formattingOptionsContainer.style.display = 'block';
                break;
            case 'document':
                this.codeInputLabel.textContent = 'Code to Document:';
                this.codeInput.placeholder = 'Paste your code here...';
                this.processBtnText.textContent = 'Generate Documentation';
                this.documentationOptionsContainer.style.display = 'block';
                break;
            case 'review':
                this.codeInputLabel.textContent = 'Code to Review:';
                this.codeInput.placeholder = 'Paste your code here...';
                this.processBtnText.textContent = 'Review Code';
                break;
            case 'compare':
                this.codeInputLabel.textContent = 'First Code Snippet:';
                this.codeInput.placeholder = 'Paste first code snippet here...';
                this.processBtnText.textContent = 'Compare Code';
                this.comparisonOptionsContainer.style.display = 'block';
                break;
        }
    }

    handleLanguageChange() {
        this.currentLanguage = this.languageSelect.value;
    }

    updateCharCount() {
        const count = this.codeInput.value.length;
        this.charCount.textContent = count;
        
        // Update character count color based on length
        if (count > 10000) {
            this.charCount.style.color = '#dc3545';
        } else if (count > 8000) {
            this.charCount.style.color = '#ffc107';
        } else {
            this.charCount.style.color = '#6c757d';
        }
    }

    async processRequest() {
        const code = this.codeInput.value.trim();
        
        if (!code) {
            this.showToast('Please enter code or prompt', 'warning');
            return;
        }

        if (code.length > 10000) {
            this.showToast('Code length exceeds maximum limit of 10,000 characters', 'danger');
            return;
        }

        // Validate comparison input
        if (this.currentAction === 'compare') {
            const code2 = this.code2Input ? this.code2Input.value.trim() : '';
            if (!code2) {
                this.showToast('Please enter second code snippet for comparison', 'warning');
                return;
            }
        }

        this.showLoading(true);
        this.hideOutput();

        try {
            const endpoint = this.getApiEndpoint();
            const payload = this.buildPayload(code);
            
            const response = await fetch(endpoint, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(payload)
            });

            const data = await response.json();

            if (!response.ok) {
                this.displayError(data.error || `HTTP ${response.status}: ${response.statusText}`);
                return;
            }

            if (data.success !== false) {
                this.displayResult(data);
            } else {
                this.displayError(data.error || 'Unknown error occurred');
            }
        } catch (error) {
            console.error('Error processing request:', error);
            this.displayError('Network error. Please try again.');
        } finally {
            this.showLoading(false);
        }
    }

    getApiEndpoint() {
        const endpoints = {
            'generate': '/api/generate',
            'debug': '/api/debug',
            'explain': '/api/explain',
            'syntax': '/api/syntax-check',
            'analyze': '/api/analyze',
            'optimize': '/api/optimize',
            'convert': '/api/convert',
            'test': '/api/test',
            'format': '/api/format',
            'document': '/api/document',
            'review': '/api/review',
            'compare': '/api/compare'
        };
        return endpoints[this.currentAction];
    }

    buildPayload(code) {
        const payload = {
            code: code,
            language: this.currentLanguage
        };

        if (this.currentAction === 'generate') {
            payload.prompt = code;
            delete payload.code;
        }

        if (this.currentAction === 'debug' && this.errorMessage.value.trim()) {
            payload.error_message = this.errorMessage.value.trim();
        }

        if (this.currentAction === 'convert') {
            payload.from_language = this.currentLanguage;
            payload.to_language = this.targetLanguageSelect.value;
        }

        if (this.currentAction === 'test') {
            payload.test_type = this.testTypeSelect.value;
        }

        if (this.currentAction === 'optimize') {
            const optimizationTypes = [];
            if (document.getElementById('optPerformance').checked) optimizationTypes.push('performance');
            if (document.getElementById('optMemory').checked) optimizationTypes.push('memory');
            if (document.getElementById('optReadability').checked) optimizationTypes.push('readability');
            if (document.getElementById('optSecurity').checked) optimizationTypes.push('security');
            if (document.getElementById('optBestPractices').checked) optimizationTypes.push('best_practices');
            payload.optimization_types = optimizationTypes;
        }

        if (this.currentAction === 'format' && this.formatStyleSelect) {
            payload.style = this.formatStyleSelect.value;
        }

        if (this.currentAction === 'document' && this.docStyleSelect) {
            payload.doc_style = this.docStyleSelect.value;
        }

        if (this.currentAction === 'compare') {
            payload.code1 = code;
            payload.code2 = this.code2Input ? this.code2Input.value.trim() : '';
            delete payload.code;
        }

        return payload;
    }

    displayResult(data) {
        let resultText = '';
        
        if (this.currentAction === 'optimize') {
            // Display optimization results
            if (data.result && data.result.optimized_code) {
                resultText = data.result.optimized_code;
                if (data.result.optimizations && data.result.optimizations.length > 0) {
                    resultText += '\n\n// Optimizations Applied:\n';
                    data.result.optimizations.forEach(opt => {
                        resultText += `// - ${opt.message}\n`;
                    });
                }
                if (data.result.improvement_score) {
                    resultText += `\n// Improvement Score: ${data.result.improvement_score.overall_score}/100\n`;
                }
            } else {
                resultText = JSON.stringify(data.result, null, 2);
            }
        } else if (this.currentAction === 'convert') {
            // Display conversion results
            if (data.result && data.result.converted_code) {
                resultText = data.result.converted_code;
                if (data.result.changes && data.result.changes.length > 0) {
                    resultText += '\n\n// Changes Made:\n';
                    data.result.changes.forEach(change => {
                        resultText += `// - ${change}\n`;
                    });
                }
                if (data.result.warnings && data.result.warnings.length > 0) {
                    resultText += '\n// Warnings:\n';
                    data.result.warnings.forEach(warning => {
                        resultText += `// - ${warning}\n`;
                    });
                }
            } else {
                resultText = JSON.stringify(data.result, null, 2);
            }
        } else if (this.currentAction === 'test') {
            // Display test results
            if (data.result && data.result.results) {
                const results = data.result.results;
                resultText = `Test Results:\n`;
                resultText += `- Tests Run: ${results.tests_run || 0}\n`;
                resultText += `- Passed: ${results.passed || 0}\n`;
                resultText += `- Failed: ${results.failed || 0}\n`;
                
                if (results.security_issues && results.security_issues.length > 0) {
                    resultText += `\nSecurity Issues:\n`;
                    results.security_issues.forEach(issue => {
                        resultText += `- ${issue.type} (${issue.severity}): ${issue.description}\n`;
                    });
                }
                
                if (results.execution_time) {
                    resultText += `\nExecution Time: ${results.execution_time}s\n`;
                }
            } else {
                resultText = JSON.stringify(data.result, null, 2);
            }
        } else if (this.currentAction === 'format') {
            // Display formatted code
            if (data.result && data.result.formatted_code) {
                resultText = data.result.formatted_code;
                if (data.result.changes_made && data.result.changes_made.length > 0) {
                    resultText += '\n\n// Formatting Changes:\n';
                    data.result.changes_made.forEach(change => {
                        resultText += `// - ${change}\n`;
                    });
                }
            } else {
                resultText = JSON.stringify(data.result, null, 2);
            }
        } else if (this.currentAction === 'document') {
            // Display documented code
            if (data.result && data.result.documented_code) {
                resultText = data.result.documented_code;
                if (data.result.changes_made && data.result.changes_made.length > 0) {
                    resultText += '\n\n// Documentation Added:\n';
                    data.result.changes_made.forEach(change => {
                        resultText += `// - ${change}\n`;
                    });
                }
            } else {
                resultText = JSON.stringify(data.result, null, 2);
            }
        } else if (this.currentAction === 'review') {
            // Display review results
            if (data.result) {
                const review = data.result;
                resultText = `Code Review Results:\n\n`;
                
                if (review.summary) {
                    resultText += `Summary:\n`;
                    resultText += `- Total Issues: ${review.summary.total_issues || 0}\n`;
                    resultText += `- Total Suggestions: ${review.summary.total_suggestions || 0}\n`;
                    resultText += `- Critical: ${review.summary.critical || 0}\n`;
                    resultText += `- High: ${review.summary.high || 0}\n`;
                    resultText += `- Medium: ${review.summary.medium || 0}\n`;
                    resultText += `- Low: ${review.summary.low || 0}\n\n`;
                }
                
                if (review.issues && review.issues.length > 0) {
                    resultText += `Issues Found:\n`;
                    review.issues.forEach((issue, idx) => {
                        resultText += `\n${idx + 1}. [${issue.severity.toUpperCase()}] ${issue.type}\n`;
                        resultText += `   Line ${issue.line}: ${issue.message}\n`;
                        resultText += `   Suggestion: ${issue.suggestion}\n`;
                    });
                }
                
                if (review.suggestions && review.suggestions.length > 0) {
                    resultText += `\nSuggestions:\n`;
                    review.suggestions.forEach((suggestion, idx) => {
                        resultText += `\n${idx + 1}. [${suggestion.severity.toUpperCase()}] ${suggestion.type}\n`;
                        resultText += `   Line ${suggestion.line}: ${suggestion.message}\n`;
                        resultText += `   Suggestion: ${suggestion.suggestion}\n`;
                    });
                }
            } else {
                resultText = JSON.stringify(data.result, null, 2);
            }
        } else if (this.currentAction === 'compare') {
            // Display comparison results
            if (data.result) {
                const comparison = data.result;
                resultText = `Code Comparison Results:\n\n`;
                
                if (comparison.statistics) {
                    const stats = comparison.statistics;
                    resultText += `Statistics:\n`;
                    resultText += `- Original Lines: ${stats.total_lines_original || 0}\n`;
                    resultText += `- Modified Lines: ${stats.total_lines_modified || 0}\n`;
                    resultText += `- Lines Added: ${stats.lines_added || 0}\n`;
                    resultText += `- Lines Removed: ${stats.lines_removed || 0}\n`;
                    resultText += `- Lines Unchanged: ${stats.lines_unchanged || 0}\n`;
                    resultText += `- Similarity: ${((stats.similarity_ratio || 0) * 100).toFixed(2)}%\n\n`;
                }
                
                if (comparison.diff && comparison.diff.length > 0) {
                    resultText += `Unified Diff:\n`;
                    comparison.diff.forEach(line => {
                        resultText += line + '\n';
                    });
                }
            } else {
                resultText = JSON.stringify(data.result, null, 2);
            }
        } else {
            // Default display for other actions
            resultText = data.result || JSON.stringify(data, null, 2);
        }
        
        this.outputCode.textContent = resultText;
        this.outputCode.className = `language-${this.getPrismLanguage(data.language || this.currentLanguage)}`;
        
        // Apply syntax highlighting
        Prism.highlightElement(this.outputCode);
        
        // Update metadata
        const timestamp = new Date(data.timestamp).toLocaleString();
        let metadata = `Processed on ${timestamp} | Language: ${data.language || this.currentLanguage}`;
        
        if (this.currentAction === 'convert' && data.result) {
            metadata += ` | Converted: ${data.result.from_language} → ${data.result.to_language}`;
        }
        
        this.outputMetadata.textContent = metadata;
        
        // Show output container
        this.outputContainer.style.display = 'block';
        this.outputContainer.classList.add('fade-in');
        
        // Store current data for download
        this.currentResult = data;
    }

    displayError(message) {
        this.errorMessageDisplay.textContent = message;
        this.errorContainer.style.display = 'block';
        this.errorContainer.classList.add('fade-in');
    }

    hideOutput() {
        this.outputContainer.style.display = 'none';
        this.errorContainer.style.display = 'none';
        this.welcomeMessage.style.display = 'none';
    }

    showLoading(show) {
        if (show) {
            this.loadingIndicator.style.display = 'block';
            this.processBtn.disabled = true;
            this.processBtn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Processing...';
        } else {
            this.loadingIndicator.style.display = 'none';
            this.processBtn.disabled = false;
            this.processBtn.innerHTML = `<i class="fas fa-play me-2"></i>${this.processBtnText.textContent}`;
        }
    }

    clearInput() {
        this.codeInput.value = '';
        this.errorMessage.value = '';
        if (this.code2Input) {
            this.code2Input.value = '';
        }
        this.updateCharCount();
        this.hideOutput();
        this.welcomeMessage.style.display = 'block';
        this.showToast('Input cleared', 'info');
    }

    async copyToClipboard() {
        try {
            const text = this.outputCode.textContent;
            await navigator.clipboard.writeText(text);
            
            // Visual feedback
            this.copyBtn.classList.add('copy-success');
            this.copyBtn.innerHTML = '<i class="fas fa-check me-1"></i>Copied!';
            
            setTimeout(() => {
                this.copyBtn.classList.remove('copy-success');
                this.copyBtn.innerHTML = '<i class="fas fa-copy me-1"></i>Copy';
            }, 2000);
            
            this.showToast('Code copied to clipboard', 'success');
        } catch (error) {
            console.error('Failed to copy:', error);
            this.showToast('Failed to copy to clipboard', 'danger');
        }
    }

    downloadCode() {
        if (!this.currentResult) {
            this.showToast('No code to download', 'warning');
            return;
        }

        const code = this.currentResult.result;
        const language = this.currentResult.language || this.currentLanguage;
        const extension = this.getFileExtension(language);
        const filename = `code_assistant_${Date.now()}.${extension}`;

        const blob = new Blob([code], { type: 'text/plain' });
        const url = URL.createObjectURL(blob);
        
        const a = document.createElement('a');
        a.href = url;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);

        this.showToast(`Code downloaded as ${filename}`, 'success');
    }

    getFileExtension(language) {
        const extensions = {
            'python': 'py',
            'javascript': 'js',
            'typescript': 'ts',
            'java': 'java',
            'cpp': 'cpp',
            'c': 'c',
            'csharp': 'cs',
            'php': 'php',
            'ruby': 'rb',
            'go': 'go',
            'rust': 'rs',
            'html': 'html',
            'css': 'css',
            'sql': 'sql',
            'swift': 'swift',
            'kotlin': 'kt'
        };
        return extensions[language] || 'txt';
    }

    getPrismLanguage(language) {
        const prismLanguages = {
            'cpp': 'cpp',
            'csharp': 'csharp',
            'javascript': 'javascript',
            'typescript': 'typescript'
        };
        return prismLanguages[language] || language;
    }

    async searchGitHub() {
        const query = this.githubSearchInput.value.trim();
        
        if (!query) {
            this.showToast('Please enter a search query', 'warning');
            return;
        }

        this.githubSearchBtn.disabled = true;
        this.githubSearchBtn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Searching...';

        try {
            const payload = {
                query: query
            };

            const language = this.githubLanguageFilter.value;
            if (language) {
                payload.language = language;
            }

            const response = await fetch('/api/github/search', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(payload)
            });

            const data = await response.json();

            if (data.success) {
                this.displayGitHubResults(data.result);
            } else {
                this.showToast(data.error || 'Search failed', 'danger');
            }
        } catch (error) {
            console.error('Error searching GitHub:', error);
            this.showToast('Network error. Please try again.', 'danger');
        } finally {
            this.githubSearchBtn.disabled = false;
            this.githubSearchBtn.innerHTML = '<i class="fas fa-search me-1"></i>Search';
        }
    }

    displayGitHubResults(results) {
        this.githubResultsContainer.innerHTML = '';

        if (!results.repositories || results.repositories.length === 0) {
            this.githubResultsContainer.innerHTML = `
                <div class="col-12">
                    <div class="alert alert-info">
                        <i class="fas fa-info-circle me-2"></i>
                        No repositories found matching your search criteria.
                    </div>
                </div>
            `;
        } else {
            results.repositories.forEach(repo => {
                const repoCard = this.createGitHubRepoCard(repo);
                this.githubResultsContainer.appendChild(repoCard);
            });
        }

        this.githubResults.style.display = 'block';
        this.githubResults.classList.add('fade-in');
    }

    createGitHubRepoCard(repo) {
        const col = document.createElement('div');
        col.className = 'col-md-6 mb-3';

        const card = document.createElement('div');
        card.className = 'github-result-card';

        const languageBadge = repo.language ? 
            `<span class="badge bg-secondary me-2">${repo.language}</span>` : '';

        const starsBadge = `<span class="badge bg-warning text-dark me-2">
            <i class="fas fa-star me-1"></i>${repo.stars}
        </span>`;

        const forksBadge = `<span class="badge bg-info me-2">
            <i class="fas fa-code-branch me-1"></i>${repo.forks}
        </span>`;

        card.innerHTML = `
            <h6>
                <a href="${repo.html_url}" target="_blank" class="text-decoration-none">
                    ${repo.full_name}
                </a>
            </h6>
            <p class="mb-2 text-muted">${repo.description || 'No description available'}</p>
            <div class="mb-2">
                ${languageBadge}
                ${starsBadge}
                ${forksBadge}
            </div>
            <div class="github-stats">
                <small><i class="fas fa-eye me-1"></i>Watchers: ${repo.watchers || 0}</small>
                <small><i class="fas fa-exclamation-circle me-1"></i>Issues: ${repo.open_issues || 0}</small>
            </div>
            <div class="mt-2">
                <small class="text-muted">
                    Updated: ${new Date(repo.updated_at).toLocaleDateString()}
                </small>
            </div>
        `;

        col.appendChild(card);
        return col;
    }

    clearGitHubResults() {
        this.githubResultsContainer.innerHTML = '';
        this.githubResults.style.display = 'none';
        this.githubSearchInput.value = '';
        this.githubLanguageFilter.value = '';
        this.showToast('GitHub results cleared', 'info');
    }

    showToast(message, type = 'info') {
        this.toastMessage.textContent = message;
        
        // Update toast styling based on type
        const toastHeader = this.toast._element.querySelector('.toast-header');
        const toastIcon = toastHeader.querySelector('i');
        
        toastIcon.className = 'fas me-2';
        
        switch (type) {
            case 'success':
                toastIcon.classList.add('fa-check-circle', 'text-success');
                break;
            case 'warning':
                toastIcon.classList.add('fa-exclamation-triangle', 'text-warning');
                break;
            case 'danger':
                toastIcon.classList.add('fa-times-circle', 'text-danger');
                break;
            case 'info':
            default:
                toastIcon.classList.add('fa-info-circle', 'text-primary');
                break;
        }
        
        this.toast.show();
    }

    // Utility method to check if code is empty or only whitespace
    isEmptyCode(code) {
        return !code || !code.trim();
    }

    // Utility method to validate code length
    validateCodeLength(code) {
        return code.length <= 10000;
    }

    // Utility method to format timestamp
    formatTimestamp(timestamp) {
        return new Date(timestamp).toLocaleString();
    }
}

// Initialize the application when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
    window.codeAssistantBot = new CodeAssistantBot();
    
    // Add some keyboard shortcuts
    document.addEventListener('keydown', (e) => {
        // Ctrl+L to clear input
        if (e.ctrlKey && e.key === 'l') {
            e.preventDefault();
            window.codeAssistantBot.clearInput();
        }
        
        // Ctrl+C to copy (when not in input field)
        if (e.ctrlKey && e.key === 'c' && !e.target.matches('input, textarea')) {
            e.preventDefault();
            window.codeAssistantBot.copyToClipboard();
        }
    });
    
    // Add page visibility handling
    document.addEventListener('visibilitychange', () => {
        if (document.hidden) {
            // Page is hidden, pause any ongoing operations
            console.log('Page hidden - pausing operations');
        } else {
            // Page is visible, resume operations
            console.log('Page visible - resuming operations');
        }
    });
    
    // Add error handling for unhandled promise rejections
    window.addEventListener('unhandledrejection', (event) => {
        console.error('Unhandled promise rejection:', event.reason);
        window.codeAssistantBot.showToast('An unexpected error occurred', 'danger');
    });
    
    // Add global error handling
    window.addEventListener('error', (event) => {
        console.error('Global error:', event.error);
        window.codeAssistantBot.showToast('An unexpected error occurred', 'danger');
    });
});
848 lines•34.1 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