should_render_bubble() || $this->is_hidden_admin_screen() ) { return; } $this->enqueue_shared_assets(); } /** * Enqueue assets on the front end. * * @return void */ public function enqueue_frontend_assets() { if ( ! $this->should_render_bubble() ) { return; } $this->enqueue_shared_assets(); } /** * Render bubble markup in wp-admin. * * @return void */ public function render_admin_bubble() { if ( ! $this->should_render_bubble() || $this->is_hidden_admin_screen() ) { return; } $this->render_bubble_markup(); } /** * Render bubble markup on the front end. * * @return void */ public function render_frontend_bubble() { if ( ! $this->should_render_bubble() ) { return; } $this->render_bubble_markup(); } /** * Determine whether the bubble should be available. * * @return bool */ private function should_render_bubble() { $enabled = rest_sanitize_boolean( get_option( 'abilities_bridge_enable_chat_bubble', false ) ); if ( ! $enabled || ! is_user_logged_in() || ! current_user_can( 'manage_options' ) ) { return false; } if ( class_exists( 'Abilities_Bridge_Welcome_Wizard' ) && ! Abilities_Bridge_Welcome_Wizard::is_setup_complete() ) { return false; } return true; } /** * Skip rendering on the main dashboard, which already contains the full chat UI. * * @return bool */ private function is_hidden_admin_screen() { if ( ! is_admin() || ! function_exists( 'get_current_screen' ) ) { return false; } $screen = get_current_screen(); return $screen && 'toplevel_page_abilities-bridge' === $screen->id; } /** * Enqueue shared assets. * * @return void */ private function enqueue_shared_assets() { $css_version = filemtime( ABILITIES_BRIDGE_PLUGIN_DIR . 'admin/css/admin-bubble.css' ); $attachments_version = filemtime( ABILITIES_BRIDGE_PLUGIN_DIR . 'admin/js/chat-attachments.js' ); $js_version = filemtime( ABILITIES_BRIDGE_PLUGIN_DIR . 'admin/js/admin-bubble.js' ); wp_enqueue_style( 'abilities-bridge-bubble', ABILITIES_BRIDGE_PLUGIN_URL . 'admin/css/admin-bubble.css', array(), $css_version ? $css_version : ABILITIES_BRIDGE_VERSION ); wp_enqueue_script( 'abilities-bridge-chat-attachments', ABILITIES_BRIDGE_PLUGIN_URL . 'admin/js/chat-attachments.js', array( 'jquery' ), $attachments_version ? $attachments_version : ABILITIES_BRIDGE_VERSION, true ); wp_enqueue_script( 'abilities-bridge-bubble', ABILITIES_BRIDGE_PLUGIN_URL . 'admin/js/admin-bubble.js', array( 'jquery', 'abilities-bridge-chat-attachments' ), $js_version ? $js_version : ABILITIES_BRIDGE_VERSION, true ); wp_localize_script( 'abilities-bridge-bubble', 'abilitiesBridgeBubbleData', array( 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'abilities_bridge_nonce' ), 'attachments' => Abilities_Bridge_Attachments::get_config(), 'i18n' => array( 'welcome' => __( 'Hi, I\'m your AI assistant. How can I help you today?', 'abilities-bridge' ), 'sending' => __( 'Processing...', 'abilities-bridge' ), 'send' => __( 'Send', 'abilities-bridge' ), 'loadFailed' => __( 'Unable to load that conversation right now.', 'abilities-bridge' ), 'connectionError' => __( 'Unable to connect to the AI service. Please try again.', 'abilities-bridge' ), 'emptyConversations' => __( 'No saved conversations yet', 'abilities-bridge' ), 'selectConversation' => __( 'Select a conversation...', 'abilities-bridge' ), 'noConversation' => __( 'No conversation selected', 'abilities-bridge' ), 'tokensUsed' => __( 'tokens used', 'abilities-bridge' ), 'ready' => __( 'Ready', 'abilities-bridge' ), 'conversationLoaded' => __( 'Conversation loaded.', 'abilities-bridge' ), 'attention' => __( 'Something needs attention.', 'abilities-bridge' ), 'loadConversationsFailed' => __( 'Unable to load saved conversations.', 'abilities-bridge' ), 'loadTokenFailed' => __( 'Unable to load token usage.', 'abilities-bridge' ), ), ) ); } /** * Render bubble markup once. * * @return void */ private function render_bubble_markup() { if ( $this->rendered ) { return; } $this->rendered = true; ?>