*/ function adminight_modes() { return array( 'light' => __( 'Light', 'adminight' ), 'dark' => __( 'Dark', 'adminight' ), 'auto' => __( 'Auto (follow the device)', 'adminight' ), ); } /** * The mode for users who have not picked one themselves. * * @return string light | dark | auto */ function adminight_default_mode() { $mode = get_option( ADMINIGHT_OPTION, 'auto' ); /** * Filters the mode used by people who have not chosen one. * * @param string $mode light, dark or auto. */ $mode = apply_filters( 'adminight_default_mode', $mode ); return array_key_exists( $mode, adminight_modes() ) ? $mode : 'auto'; } /** * A user's mode: their own choice, or the site default. * * @param int $user_id User ID; the current user when 0. * @return string light | dark | auto */ function adminight_get_mode( $user_id = 0 ) { $user_id = $user_id ? $user_id : get_current_user_id(); $mode = $user_id ? get_user_meta( $user_id, ADMINIGHT_META, true ) : ''; return array_key_exists( $mode, adminight_modes() ) ? $mode : adminight_default_mode(); } /** * Asset version: the plugin version, or the file's time while SCRIPT_DEBUG is on, so edits show up at once. * * @param string $file File name inside assets/. * @return string */ function adminight_asset_version( $file ) { if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) { return (string) filemtime( __DIR__ . '/assets/' . $file ); } return ADMINIGHT_VERSION; } /** * Sets the class on before the page paints, so a dark screen never flashes white. */ function adminight_head_script() { $script = sprintf( '(function(d,m){var q=window.matchMedia("(prefers-color-scheme: dark)");function a(){d.classList.toggle("adminight-on",m==="dark"||(m==="auto"&&q.matches));}d.setAttribute("data-adminight-mode",m);a();if(q.addEventListener){q.addEventListener("change",function(){m=d.getAttribute("data-adminight-mode");a();});}})(document.documentElement,%s);', wp_json_encode( adminight_get_mode() ) ); wp_print_inline_script_tag( $script, array( 'id' => 'adminight-mode' ) ); } add_action( 'admin_head', 'adminight_head_script', 0 ); /** * Stylesheet and the toolbar switch. */ function adminight_enqueue() { wp_enqueue_style( 'adminight', ADMINIGHT_URL . 'assets/adminight.css', array(), adminight_asset_version( 'adminight.css' ) ); wp_enqueue_script( 'adminight', ADMINIGHT_URL . 'assets/adminight.js', array(), adminight_asset_version( 'adminight.js' ), true ); wp_localize_script( 'adminight', 'AdminightSettings', array( 'ajax' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'adminight_mode' ), 'labels' => adminight_modes(), ) ); } add_action( 'admin_enqueue_scripts', 'adminight_enqueue' ); // The Customizer is its own screen with its own hooks. add_action( 'customize_controls_enqueue_scripts', 'adminight_enqueue' ); add_action( 'customize_controls_print_styles', 'adminight_head_script', 0 ); /** * The login screen has no user yet, so it follows the site default (Auto = the device's setting). */ function adminight_login_style() { $mode = adminight_default_mode(); if ( 'light' === $mode ) { return; } wp_enqueue_style( 'adminight-login', ADMINIGHT_URL . 'assets/adminight-login.css', array( 'login' ), adminight_asset_version( 'adminight-login.css' ), 'dark' === $mode ? 'all' : '(prefers-color-scheme: dark)' ); } add_action( 'login_enqueue_scripts', 'adminight_login_style' ); /** * The classic editor writes inside its own frame, so it gets its own small stylesheet and a class with the mode. * * @param string $css Comma-separated stylesheet URLs. * @return string */ function adminight_mce_css( $css ) { if ( ! is_admin() ) { return $css; } $url = ADMINIGHT_URL . 'assets/adminight-editor.css?ver=' . adminight_asset_version( 'adminight-editor.css' ); return $css ? $css . ',' . $url : $url; } add_filter( 'mce_css', 'adminight_mce_css' ); /** * Adds the mode to the classic editor's body class. * * @param array $init TinyMCE settings. * @return array */ function adminight_mce_body_class( $init ) { if ( is_admin() ) { $init['body_class'] = trim( ( isset( $init['body_class'] ) ? $init['body_class'] : '' ) . ' adminight-mce-' . adminight_get_mode() ); } return $init; } add_filter( 'tiny_mce_before_init', 'adminight_mce_body_class' ); /** * Toolbar switch, inside wp-admin only. * * @param WP_Admin_Bar $bar The toolbar. */ function adminight_bar_node( $bar ) { if ( ! is_admin() || ! is_user_logged_in() ) { return; } $mode = adminight_get_mode(); $labels = adminight_modes(); $bar->add_node( array( 'id' => 'adminight', 'parent' => 'top-secondary', 'title' => '' . esc_html( $labels[ $mode ] ) . '', 'href' => '#', 'meta' => array( 'title' => __( 'Admin colours: Light, Dark or Auto', 'adminight' ), 'class' => 'adminight-ab', ), ) ); foreach ( $labels as $key => $label ) { $bar->add_node( array( 'id' => 'adminight-' . $key, 'parent' => 'adminight', 'title' => esc_html( $label ), 'href' => '#', 'meta' => array( 'class' => 'adminight-ab-choice' . ( $key === $mode ? ' adminight-current' : '' ) ), ) ); } } add_action( 'admin_bar_menu', 'adminight_bar_node', 100 ); /** * Saves the choice made in the toolbar. */ function adminight_ajax_set_mode() { check_ajax_referer( 'adminight_mode', 'nonce' ); if ( ! current_user_can( 'read' ) ) { wp_send_json_error( null, 403 ); } $mode = isset( $_POST['mode'] ) ? sanitize_key( wp_unslash( $_POST['mode'] ) ) : ''; if ( ! array_key_exists( $mode, adminight_modes() ) ) { wp_send_json_error( null, 400 ); } update_user_meta( get_current_user_id(), ADMINIGHT_META, $mode ); wp_send_json_success( array( 'mode' => $mode ) ); } add_action( 'wp_ajax_adminight_set_mode', 'adminight_ajax_set_mode' ); /** * Radio buttons for one of the three modes. * * @param string $name Field name. * @param string $current Selected mode. */ function adminight_mode_radios( $name, $current ) { foreach ( adminight_modes() as $key => $label ) { printf( '
', esc_attr( $name ), esc_attr( $key ), checked( $current, $key, false ), esc_html( $label ) ); } } /** * Users → Profile. * * @param WP_User $user The user being edited. */ function adminight_profile_field( $user ) { ?>
ID ) ); ?>
'string', 'default' => 'auto', 'sanitize_callback' => 'adminight_sanitize_mode', 'show_in_rest' => false, ) ); add_settings_field( 'adminight-default', __( 'Admin dark mode', 'adminight' ), 'adminight_setting_field', 'general', 'default' ); } add_action( 'admin_init', 'adminight_register_setting' ); /** * Keeps the stored value to one of the three modes. * * @param mixed $value Submitted value. * @return string */ function adminight_sanitize_mode( $value ) { $value = sanitize_key( (string) $value ); return array_key_exists( $value, adminight_modes() ) ? $value : 'auto'; } /** * The field on Settings → General. */ function adminight_setting_field() { ?>

' . esc_html__( 'Settings', 'adminight' ) . '' ); return $links; } add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'adminight_action_links' );