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
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,18 @@ public function __construct() {

public function loadHome() {
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$this->saveCharacterOrder();
?>
<div class="updated"><p><strong>Character settings succesfully saved.</strong></p></div>
<?php
check_admin_referer('acore_character_order', 'acore_character_order_nonce');
if (isset($_POST["acore_reset_order"])) {
$this->resetCharacterOrder();
?>
<div class="updated"><p><strong>Character order reset successfully.</strong></p></div>
<?php
} else {
$this->saveCharacterOrder();
?>
<div class="updated"><p><strong>Character settings succesfully saved.</strong></p></div>
Comment thread
TheSCREWEDSoftware marked this conversation as resolved.
<?php
}
}

$accId = ACoreServices::I()->getAcoreAccountId();
Expand All @@ -38,6 +46,16 @@ public function getView() {
return $this->view;
}

private function resetCharacterOrder() {
$accId = ACoreServices::I()->getAcoreAccountId();
$conn = ACoreServices::I()->getCharacterEm()->getConnection();
$stmt = $conn->prepare(
"UPDATE `characters` SET `order` = NULL WHERE `account` = ? AND `deleteDate` IS NULL"
);
$stmt->bindValue(1, $accId);
$stmt->executeQuery();
}

private function saveCharacterOrder() {
if (!isset($_POST) || !isset($_POST["characterorder"])) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace ACore\Components\CharactersMenu;

use ACore\Utils\AcoreCharColors;

class CharactersView {
private $controller;

Expand All @@ -16,44 +18,47 @@ public function __construct($controller) {
public function getHomeRender($characters) {
ob_start();
wp_enqueue_style('bootstrap-css', '//cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css', array(), '5.1.3');
wp_enqueue_style('acore-css', ACORE_URL_PLG . 'web/assets/css/main.css', array(), '0.1');
wp_enqueue_style('acore-css', ACORE_URL_PLG . 'web/assets/css/main.css', array(), '0.5');
wp_enqueue_script('bootstrap-js', '//cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js', array(), '5.1.3');
wp_enqueue_script('jquery-ui-sortable');
?>
<div class="wrap">
<h2>Characters Settings</h2>
<p>Check some details and configure of your characters.</p>

<div class="row">
<div class="col-sm-4">
<div class="card">
<div class="card-body">
<h3>Order</h3>
<p>Change the order in which the characters appear in your in-game character selection screen.</p>
<h3>Order Character Screen</h3>
<p>Change the order in which the characters appear in your in-game character selection screen, by dragging them, matches in-game position.</p>
Comment thread
TheSCREWEDSoftware marked this conversation as resolved.
<hr>
<form action="" method="POST" novalidate="novalidate">
<?php wp_nonce_field('acore_character_order', 'acore_character_order_nonce'); ?>

<ul id="acore-characters-order" class="list-unstyled">
<?php foreach ($characters as $char) { ?>
<ul id="acore-characters-order" class="acore-char-list list-unstyled">
<?php $charPos = 0; foreach ($characters as $char) {
$clsStyle = AcoreCharColors::rowStyle(intval($char["class"]), intval($char["race"]));
$charPos++;
$displayPos = $char['order'] !== null ? intval($char['order']) + 1 : $charPos;
?>
<li>
<div class="menu-item-bar">
<div class="menu-item-handle ui-sortable-handle">
<span class="item-title menu-item-title"><?= $char["name"] ?></span>
<span class="item-controls">
<span class="item-type">
level <?= $char["level"] ?>&ensp;
<img src="<?= ACORE_URL_PLG . "web/assets/race/" . $char["race"] . ($char["gender"] == 0 ? "m" : "f") . ".webp"; ?>">
<img src="<?= ACORE_URL_PLG . "web/assets/class/" . $char["class"] . ".webp"; ?>">
</span>
</div>
<div class="acore-char-row" style="<?= esc_attr($clsStyle) ?>">
<span class="acore-char-pos"><?= $displayPos ?></span>
<span class="acore-char-name"><?= esc_html($char["name"]) ?></span>
<span class="acore-char-meta">
<span class="acore-level" data-exp="<?= AcoreCharColors::expansionSlug(intval($char["level"])) ?>" title="<?= esc_attr(AcoreCharColors::expansionLabel(intval($char["level"]))) ?>">Level <?= intval($char["level"]) ?></span>
<img class="race-icon" height="32" width="32" title="<?= esc_attr(AcoreCharColors::getRaceName(intval($char["race"]))) ?>" src="<?= esc_url(ACORE_URL_PLG . "web/assets/race/" . intval($char["race"]) . (intval($char["gender"]) == 0 ? "m" : "f") . ".webp") ?>">
<img class="class-icon" height="32" width="32" title="<?= esc_attr(AcoreCharColors::getClassName(intval($char["class"]))) ?>" src="<?= esc_url(ACORE_URL_PLG . "web/assets/class/" . intval($char["class"]) . ".webp") ?>">
</span>
</div>
<input name="characterorder[]" value="<?= $char["guid"] ?>">
<input type="hidden" name="characterorder[]" value="<?= esc_attr($char["guid"]) ?>">
</li>
<?php } ?>
</ul>

<?php if (!empty($characters)) { ?>
<input type="submit" name="submit" class="button button-primary" value="Save Order">
<div style="display:flex; justify-content:space-between; align-items:center; margin-top:8px;">
<input type="submit" name="submit" class="button button-primary" value="Save Order">
<input type="submit" name="acore_reset_order" class="button acore-btn-danger" value="Reset Order">
</div>
<?php } ?>
</form>
</div>
Expand All @@ -62,12 +67,23 @@ public function getHomeRender($characters) {
</div>
</div>

<script type="text/javascript">
jQuery(document).ready(function($) {
$("#acore-characters-order").sortable();
<!-- .acore-btn-danger styling lives in theme.css (shared light/dark) -->

<script>
jQuery(document).ready(function($) {
$("#acore-characters-order").sortable({
update: function(event, ui) {
var order = [];
$("#acore-characters-order li").each(function(index) {
var input = $(this).find("input[name='characterorder[]']");
order.push(input.val());
$(this).find(".acore-char-pos").text(index + 1);
});
}
});
$("#acore-characters-order").disableSelection();
});
</script>

<?php
return ob_get_clean();
}
Expand Down
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";
}
Loading
Loading