*/
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 ) {
?>