radio_get_state(), 'stations' => radio_get_stations_flat(), 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'radio_save_state' ), 'strings' => array( 'play' => __( 'Play', 'radio' ), 'pause' => __( 'Pause', 'radio' ), 'loading' => __( 'Loading…', 'radio' ), 'error' => __( 'Stream error — try another station.', 'radio' ), 'saveError' => __( 'Preferences not saved — check your connection.', 'radio' ), 'mute' => __( 'Mute', 'radio' ), 'unmute' => __( 'Unmute', 'radio' ), 'nowPlaying' => __( 'Now Playing', 'radio' ), 'volume' => __( 'Volume', 'radio' ), 'station' => __( 'Station', 'radio' ), ), ) ); } /** * AJAX endpoint for saving per-user state (station / volume changes). * Avoids a full page reload on every interaction. */ add_action( 'wp_ajax_radio_save_state', 'radio_ajax_save_state' ); function radio_ajax_save_state() { if ( ! is_user_logged_in() ) { wp_send_json_error( 'Not logged in.', 401 ); } check_ajax_referer( 'radio_save_state', 'nonce' ); $patch = array(); if ( isset( $_POST['station_id'] ) ) { $patch['station_id'] = sanitize_key( wp_unslash( $_POST['station_id'] ) ); } if ( isset( $_POST['volume'] ) ) { $patch['volume'] = max( 0.0, min( 1.0, (float) $_POST['volume'] ) ); } if ( empty( $patch ) ) { wp_send_json_error( 'Nothing to save.', 400 ); } radio_update_state( $patch ); wp_send_json_success( radio_get_state() ); } /** * Surface the user's theme choice (auto/light/dark) to CSS as a body * class. `radio-theme-dark` forces dark; `radio-theme-auto` lets the * CSS respect `prefers-color-scheme`; `radio-theme-light` is the * default no-op. */ add_filter( 'admin_body_class', 'radio_admin_body_class' ); function radio_admin_body_class( $classes ) { if ( ! is_user_logged_in() ) { return $classes; } $state = radio_get_state(); $theme = isset( $state['theme'] ) ? $state['theme'] : 'auto'; if ( ! in_array( $theme, array( 'auto', 'light', 'dark' ), true ) ) { $theme = 'auto'; } return $classes . ' radio-theme-' . $theme; } /** * Activation hook: ensure the version option is set so the updater can * track it. */ register_activation_hook( __FILE__, 'radio_on_activate' ); function radio_on_activate() { if ( false === get_option( 'radio_version' ) ) { add_option( 'radio_version', RADIO_VERSION ); } else { update_option( 'radio_version', RADIO_VERSION ); } }