// BotApp Extensions - Injected by Tauri into botui's suite // Adds app-only guides and native functionality // // This script runs only in the Tauri app context and extends // the botui suite with desktop-specific features. (function() { 'use strict'; // App-only guides that will be injected into the suite navigation const APP_GUIDES = [ { id: 'local-files', label: 'Local Files', icon: ` `, hxGet: '/app/guides/local-files.html', description: 'Access and manage files on your device' }, { id: 'native-settings', label: 'App Settings', icon: ` `, hxGet: '/app/guides/native-settings.html', description: 'Configure desktop app settings' } ]; // CSS for app-only elements const APP_STYLES = ` .app-grid-separator { grid-column: 1 / -1; display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0; margin-top: 0.5rem; border-top: 1px solid var(--border-color, #e0e0e0); } .app-grid-separator span { font-size: 0.75rem; color: var(--text-secondary, #666); text-transform: uppercase; letter-spacing: 0.05em; } .app-item.app-only { position: relative; } .app-item.app-only::after { content: ''; position: absolute; top: 4px; right: 4px; width: 6px; height: 6px; background: var(--accent-color, #4a90d9); border-radius: 50%; } `; /** * Inject app-specific styles */ function injectStyles() { const styleEl = document.createElement('style'); styleEl.id = 'botapp-styles'; styleEl.textContent = APP_STYLES; document.head.appendChild(styleEl); } /** * Inject app-only guides into the suite navigation */ function injectAppGuides() { const grid = document.querySelector('.app-grid'); if (!grid) { // Retry if grid not found yet (page still loading) setTimeout(injectAppGuides, 100); return; } // Check if already injected if (document.querySelector('.app-grid-separator')) { return; } // Add separator const separator = document.createElement('div'); separator.className = 'app-grid-separator'; separator.innerHTML = 'Desktop Features'; grid.appendChild(separator); // Add app-only guides APP_GUIDES.forEach(guide => { const item = document.createElement('a'); item.className = 'app-item app-only'; item.href = `#${guide.id}`; item.dataset.section = guide.id; item.setAttribute('role', 'menuitem'); item.setAttribute('aria-label', guide.description || guide.label); item.setAttribute('hx-get', guide.hxGet); item.setAttribute('hx-target', '#main-content'); item.setAttribute('hx-push-url', 'true'); item.innerHTML = ` ${guide.label} `; grid.appendChild(item); }); // Re-process HTMX on new elements if (window.htmx) { htmx.process(grid); } console.log('[BotApp] App guides injected successfully'); } /** * Setup Tauri event listeners */ function setupTauriEvents() { if (!window.__TAURI__) { console.warn('[BotApp] Tauri API not available'); return; } const { listen } = window.__TAURI__.event; // Listen for upload progress events listen('upload_progress', (event) => { const progress = event.payload; const progressEl = document.getElementById('upload-progress'); if (progressEl) { progressEl.style.width = `${progress}%`; progressEl.textContent = `${Math.round(progress)}%`; } }); console.log('[BotApp] Tauri event listeners registered'); } /** * Initialize BotApp extensions */ function init() { console.log('[BotApp] Initializing app extensions...'); // Inject styles injectStyles(); // Inject app guides injectAppGuides(); // Setup Tauri events setupTauriEvents(); console.log('[BotApp] App extensions initialized'); } // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } // Expose BotApp API globally window.BotApp = { isApp: true, version: '6.1.0', guides: APP_GUIDES, // Invoke Tauri commands invoke: async function(cmd, args) { if (!window.__TAURI__) { throw new Error('Tauri API not available'); } return window.__TAURI__.core.invoke(cmd, args); }, // File system helpers fs: { listFiles: (path) => window.BotApp.invoke('list_files', { path }), uploadFile: (srcPath, destPath) => window.BotApp.invoke('upload_file', { srcPath, destPath }), createFolder: (path, name) => window.BotApp.invoke('create_folder', { path, name }), deletePath: (path) => window.BotApp.invoke('delete_path', { path }), getHomeDir: () => window.BotApp.invoke('get_home_dir'), }, // Show native notification notify: async function(title, body) { if (window.__TAURI__?.notification) { await window.__TAURI__.notification.sendNotification({ title, body }); } }, // Open native file dialog openFileDialog: async function(options = {}) { if (!window.__TAURI__?.dialog) { throw new Error('Dialog API not available'); } return window.__TAURI__.dialog.open(options); }, // Open native save dialog saveFileDialog: async function(options = {}) { if (!window.__TAURI__?.dialog) { throw new Error('Dialog API not available'); } return window.__TAURI__.dialog.save(options); } }; })();