Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 149 additions & 0 deletions src/acore-wp-plugin/src/Hooks/Various/DarkMode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
<?php

namespace ACore\Hooks\Various;

add_action('admin_bar_menu', __NAMESPACE__ . '\acore_dark_mode_bar_node', 999);

function acore_dark_mode_bar_node($wp_admin_bar) {
if (!is_user_logged_in() || !is_admin()) {
return;
}

$is_dark = get_user_meta(get_current_user_id(), 'acore_dark_mode', true) === '1';

$wp_admin_bar->add_node([
'id' => 'acore-dark-mode',
'parent' => 'top-secondary',
'title' => '<span id="acore-dm-icon">' . ($is_dark ? '&#9728;' : '&#9790;') . '</span>',
'href' => '#',
'meta' => ['title' => $is_dark ? 'Switch to light mode' : 'Switch to dark mode'],
]);
}

add_filter('admin_body_class', __NAMESPACE__ . '\acore_dark_mode_body_class');

function acore_dark_mode_body_class($classes) {
if (get_user_meta(get_current_user_id(), 'acore_dark_mode', true) === '1') {
$classes .= ' acore-dark-mode';
}
return $classes;
}

add_action('admin_enqueue_scripts', __NAMESPACE__ . '\acore_dark_mode_enqueue');

function acore_dark_mode_enqueue() {
wp_enqueue_style('acore-css', ACORE_URL_PLG . 'web/assets/css/main.css', [], '3.0');
wp_enqueue_style('acore-dark-mode', ACORE_URL_PLG . 'web/assets/css/dark-mode.css', ['acore-css'], '3.7');
// Central light/dark theme layer (edit colours here). Loaded last so it wins.
wp_enqueue_style('acore-theme', ACORE_URL_PLG . 'web/assets/css/theme.css', ['acore-dark-mode'], '3.7');

$nonce = wp_create_nonce('acore_dark_mode');
wp_add_inline_script('jquery-core', acore_dark_mode_js($nonce));
}

/*
* Late inline <style> injected at end of admin head (priority 9999) so it always
* wins the cascade over WordPress color-scheme CSS and any plugin stylesheets,
* even those that use !important.
*/
add_action('admin_head', __NAMESPACE__ . '\acore_dark_mode_late_styles', 9999);

function acore_dark_mode_late_styles() {
// Always: WP2FA modal size - applies in both light and dark mode
?>
<style id="acore-wp2fa-modal-size">
.wp2fa-modal .modal__container {
max-width: 900px !important;
width: 85vw !important;
min-height: 480px !important;
font-size: 16px !important;
padding: 40px !important;
}
.wp2fa-modal .modal__content { font-size: 16px !important; }
.wp2fa-modal .modal__content * { font-size: inherit !important; }
</style>
<?php

if (get_user_meta(get_current_user_id(), 'acore_dark_mode', true) !== '1') {
return;
}
?>
<style id="acore-dark-mode-late">

/* character list rows - handled by dark-mode.css; only overrides needed here */
.acore-dark-mode .acore-char-meta img.race-icon { border-color: color-mix(in srgb, var(--faction-color, rgba(255,255,255,0.15)) 70%, transparent) !important; }
.acore-dark-mode .acore-char-meta img.class-icon { border-color: color-mix(in srgb, var(--cls-dark, rgba(255,255,255,0.15)) 70%, transparent) !important; }
.acore-dark-mode #acore-characters-mail .acore-char-row.active { background: #21262d !important; border-top-color: var(--faction-color, #58a6ff) !important; border-right-color: var(--faction-color, #58a6ff) !important; border-bottom-color: var(--faction-color, #58a6ff) !important; border-top-width: 3px !important; border-right-width: 3px !important; border-bottom-width: 3px !important; }

/* Bootstrap card */
.acore-dark-mode .card,
.acore-dark-mode .card-body,
.acore-dark-mode .card-header { background-color: #161b22 !important; border-color: #30363d !important; color: #c9d1d9 !important; }

/* mail entries - border color set by JS inline (faction/class), only bg overridden */
.acore-dark-mode .mail-entry { background: #161b22 !important; }
.acore-dark-mode .mail-recipient,
.acore-dark-mode .mail-items { background: #0d1117 !important; }
.acore-dark-mode .mail-entry *,
.acore-dark-mode .mail-recipient *,
.acore-dark-mode .mail-meta { color: #c9d1d9 !important; }

/* myCred / points widgets */
.acore-dark-mode [id^="mycred"],
.acore-dark-mode [class*="mycred"] { background: #161b22 !important; border-color: #30363d !important; color: #c9d1d9 !important; }
.acore-dark-mode [id^="mycred"] *,
.acore-dark-mode [class*="mycred"] * { color: #c9d1d9 !important; }

/* Bootstrap form-select */
.acore-dark-mode .form-select { background-color: #0d1117 !important; border-color: #30363d !important; color: #c9d1d9 !important; }

/* hr */
.acore-dark-mode hr { border-color: #30363d !important; }

</style>
<?php
}

add_action('wp_ajax_acore_toggle_dark_mode', __NAMESPACE__ . '\acore_ajax_toggle_dark_mode');

function acore_ajax_toggle_dark_mode() {
check_ajax_referer('acore_dark_mode', 'nonce');
$user_id = get_current_user_id();
$new = get_user_meta($user_id, 'acore_dark_mode', true) === '1' ? '0' : '1';
update_user_meta($user_id, 'acore_dark_mode', $new);
wp_send_json_success(['dark' => $new === '1']);
}

function acore_dark_mode_js(string $nonce): string {
return <<<JS
(function($){
var nonce = '{$nonce}';
$(document).on('click', '#wp-admin-bar-acore-dark-mode > a', function(e){
e.preventDefault();
$.post(ajaxurl, { action: 'acore_toggle_dark_mode', nonce: nonce }, function(res){
if (!res.success) return;
var dark = res.data.dark;
$('body').toggleClass('acore-dark-mode', dark);
$('#acore-dm-icon').html(dark ? '&#9728;' : '&#9790;');
$('#wp-admin-bar-acore-dark-mode > a').attr('title', dark ? 'Switch to light mode' : 'Switch to dark mode');
});
});
})(jQuery);
JS;
}

/*
* The WP 2FA setup wizard (profile.php?page=wp-2fa-setup) renders a sealed
* full-page template that only prints its own stylesheets. It exposes
* `wp_2fa_setup_page_scripts` inside its <head>; we use it to inject theme.css
* (whose body.wp2fa-setup rules are dark) only when the user has dark mode on.
*/
add_action('wp_2fa_setup_page_scripts', __NAMESPACE__ . '\acore_dark_mode_wizard_css');

function acore_dark_mode_wizard_css() {
if (get_user_meta(get_current_user_id(), 'acore_dark_mode', true) !== '1') {
return;
}
echo '<link rel="stylesheet" id="acore-theme-wizard-css" media="all" href="'
. esc_url(ACORE_URL_PLG . 'web/assets/css/theme.css') . '?ver=3.7" />' . "\n";
}
109 changes: 109 additions & 0 deletions src/acore-wp-plugin/src/Utils/AcoreCharColors.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php

namespace ACore\Utils;

class AcoreCharColors {

/**
* WotLK class colors.
* light = adjusted for visibility on white backgrounds (Rogue/Priest darkened)
* dark = original WoW colors, bright enough for dark backgrounds
*/
const CLASS_NAMES = [
1 => 'Warrior',
2 => 'Paladin',
3 => 'Hunter',
4 => 'Rogue',
5 => 'Priest',
6 => 'Death Knight',
7 => 'Shaman',
8 => 'Mage',
9 => 'Warlock',
11 => 'Druid',
];

const CLASS_COLORS = [
1 => ['light' => '#C69B6D', 'dark' => '#C69B6D'], // Warrior
2 => ['light' => '#F48CBA', 'dark' => '#F48CBA'], // Paladin
3 => ['light' => '#AAD372', 'dark' => '#AAD372'], // Hunter
4 => ['light' => '#C8A800', 'dark' => '#FFF468'], // Rogue (yellow → darkened for light bg)
5 => ['light' => '#909090', 'dark' => '#E0E0E0'], // Priest (white → grey for light bg)
6 => ['light' => '#C41E3A', 'dark' => '#FF3355'], // Death Knight
7 => ['light' => '#0070DD', 'dark' => '#3399FF'], // Shaman
8 => ['light' => '#3FC7EB', 'dark' => '#3FC7EB'], // Mage
9 => ['light' => '#8788EE', 'dark' => '#9A9BFF'], // Warlock
11 => ['light' => '#FF7C0A', 'dark' => '#FF7C0A'], // Druid
];

const FALLBACK_LIGHT = '#646970';
const FALLBACK_DARK = '#8b949e';

const RACE_NAMES = [
1 => 'Human',
2 => 'Orc',
3 => 'Dwarf',
4 => 'Night Elf',
5 => 'Undead',
6 => 'Tauren',
7 => 'Gnome',
8 => 'Troll',
10 => 'Blood Elf',
11 => 'Draenei',
];

/** Maps race ID → faction. */
const RACE_FACTION = [
1 => 'alliance', // Human
2 => 'horde', // Orc
3 => 'alliance', // Dwarf
4 => 'alliance', // Night Elf
5 => 'horde', // Undead
6 => 'horde', // Tauren
7 => 'alliance', // Gnome
8 => 'horde', // Troll
10 => 'horde', // Blood Elf
11 => 'alliance', // Draenei
];

public static function getClassName(int $classId): string {
return self::CLASS_NAMES[$classId] ?? 'Unknown';
}

public static function getRaceName(int $raceId): string {
return self::RACE_NAMES[$raceId] ?? 'Unknown';
}

public static function getFaction(int $raceId): string {
return self::RACE_FACTION[$raceId] ?? 'unknown';
}

/**
* Returns inline style string for a character row.
* Uses CSS custom properties so dark-mode.css can override via color-mix.
*/
public static function rowStyle(int $classId, int $raceId): string {
$cls = self::CLASS_COLORS[$classId] ?? ['light' => self::FALLBACK_LIGHT, 'dark' => self::FALLBACK_DARK];
$faction = self::RACE_FACTION[$raceId] ?? 'unknown';
$fLight = $faction === 'alliance' ? '#3FACF4' : '#FF653D';
$fDark = $faction === 'alliance' ? '#3FACF4' : '#FF653D';
return sprintf(
'--cls-light:%s; --cls-dark:%s; --faction-color:%s; border-top:2px solid %s; border-right:2px solid %s; border-bottom:2px solid %s; border-left:4px solid %s;',
$cls['light'], $cls['dark'], $fLight,
$fLight, $fLight, $fLight, $cls['light']
);
Comment thread
TheSCREWEDSoftware marked this conversation as resolved.
}

/** Returns the expansion slug for a level, used as data-exp attribute. */
public static function expansionSlug(int $level): string {
if ($level <= 60) return 'vanilla';
if ($level <= 70) return 'tbc';
return 'wrath';
}

/** Returns the expansion label for a level, used as title attribute. */
public static function expansionLabel(int $level): string {
if ($level <= 60) return 'Classic';
if ($level <= 70) return 'The Burning Crusade';
return 'Wrath of the Lich King';
}
}
2 changes: 2 additions & 0 deletions src/acore-wp-plugin/src/boot.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
define('FS_METHOD', 'direct');

require_once ACORE_PATH_PLG . 'src/Utils/AcoreUtils.php';
require_once ACORE_PATH_PLG . 'src/Utils/AcoreCharColors.php';

require_once ACORE_PATH_PLG . 'src/Deps/class-tgm-plugin-activation.php';

Expand All @@ -18,6 +19,7 @@
require_once ACORE_PATH_PLG . 'src/Hooks/Subscriptions/sync_subscription.php';

require_once ACORE_PATH_PLG . 'src/Hooks/Various/tgmplugin_activator.php';
require_once ACORE_PATH_PLG . 'src/Hooks/Various/DarkMode.php';

require_once ACORE_PATH_PLG . 'src/Hooks/User/Include.php';

Expand Down
Loading
Loading