mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 02:43:44 +00:00
feat(dashboard): account and character pages update without reloading
Actions on an account (ban, mute, lock, GM level, email) and on a character (edit, restoring a version, saving its XML) show the result in place (reloadInPlace) instead of reloading the page. Deleting an account goes back to Accounts without leaving the deleted account in the history. After an in-place update (dash:refreshed) the pages show the server's values again the way they do on load: last logins and the mute end in the browser's time, and the GM level picker (unless a new level is being picked). Check: lock and unlock an account: the badge changes with no reload. Change an account's GM level from another tab: the first tab's level picker follows. Edit a character's items: the page updates when the dialog closes. A character's last login updates when they log in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -132,7 +132,7 @@
|
||||
var body = buildEdit();
|
||||
if (!confirm('Save these changes? The player is disconnected if online.')) return;
|
||||
api.action('/api/characters/' + config.id + '/edit', body).then(function (d) { return d.result; }).then(function (r) {
|
||||
if (r && r.success) { bootstrap.Modal.getInstance(document.getElementById('editModal')).hide(); setTimeout(function () { location.reload(); }, 600); }
|
||||
if (r && r.success) { bootstrap.Modal.getInstance(document.getElementById('editModal')).hide(); setTimeout(reloadInPlace, 600); }
|
||||
}).catch(function () {});
|
||||
});
|
||||
}
|
||||
@@ -205,7 +205,7 @@
|
||||
var restore = e.target.closest('[data-restore]');
|
||||
if (!restore || !confirm('Put the character back to this version? The player is disconnected if online, and the current version is kept in the history.')) return;
|
||||
api.action('/api/snapshots/' + restore.dataset.restore + '/restore', {}).then(function (d) { return d.result; }).then(function (r) {
|
||||
if (r && r.success) setTimeout(function () { location.reload(); }, 600);
|
||||
if (r && r.success) setTimeout(reloadInPlace, 600);
|
||||
}).catch(function () {});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -485,9 +485,19 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
loadEmailStatus();
|
||||
var ownEmail = document.getElementById('ownEmail');
|
||||
if (ownEmail) ownEmail.value = accountEl.getAttribute('data-email') || '';
|
||||
showServerValues();
|
||||
// Update in place when someone else changes this account
|
||||
Live.refreshPage('accounts', accountId);
|
||||
});
|
||||
// After an in-place update (nav.js) the server's values may have changed: show them the same way again
|
||||
document.addEventListener('dash:refreshed', showServerValues);
|
||||
|
||||
// The GM level, mute and last logins as the server has them, shown in the browser's time
|
||||
function showServerValues() {
|
||||
var gmSelect = document.getElementById('gmLevelSelect');
|
||||
if (gmSelect) {
|
||||
gmSelect.value = accountEl.getAttribute('data-gm-level');
|
||||
// Not while someone is picking a new level
|
||||
if (gmSelect && (!gmSelect.dataset.shown || gmSelect.value === gmSelect.dataset.shown)) {
|
||||
gmSelect.value = gmSelect.dataset.shown = accountEl.getAttribute('data-gm-level');
|
||||
// Only operators may grant their own level or higher
|
||||
Array.prototype.forEach.call(gmSelect.options, function (opt) {
|
||||
if (DASH.gmLevel < 9 && parseInt(opt.value, 10) >= DASH.gmLevel) opt.disabled = true;
|
||||
@@ -503,13 +513,11 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
var ts = parseInt(el.getAttribute('data-ts'), 10);
|
||||
el.textContent = ts > 0 ? fmt.unix(ts) : 'Never';
|
||||
});
|
||||
// Reload when someone else changes this account
|
||||
Live.refreshPage('accounts', accountId);
|
||||
});
|
||||
}
|
||||
|
||||
// Reload once the change (and any live action it started, like a kick) has finished
|
||||
// Show the page again once the change (and any live action it started, like a kick) has finished
|
||||
function reloadOnSuccess(promise) {
|
||||
promise.then(function (d) { return d.result || d; }).then(function () { location.reload(); }).catch(function () {});
|
||||
promise.then(function (d) { return d.result || d; }).then(function () { reloadInPlace(); }).catch(function () {});
|
||||
}
|
||||
|
||||
var reset2faBtn = document.getElementById('reset2faBtn');
|
||||
@@ -610,7 +618,7 @@ function deleteAccount() {
|
||||
if (!confirm('PERMANENTLY delete this account and all its characters? This cannot be undone.')) return;
|
||||
if (!confirm('Are you absolutely sure?')) return;
|
||||
}
|
||||
api.action(base + '/delete', body).then(function (d) { return d.result; }).then(function () { window.location.href = accountEl.dataset.self ? '/login' : '/accounts'; }).catch(function () {});
|
||||
api.action(base + '/delete', body).then(function (d) { return d.result; }).then(function () { if (accountEl.dataset.self) window.location.href = '/login'; else goTo('/accounts', { replace: true }); }).catch(function () {});
|
||||
}
|
||||
function resetPassword() {
|
||||
var pwd = document.getElementById('newPwd').value;
|
||||
@@ -643,7 +651,7 @@ function saveOwnEmail() {
|
||||
pwd.value = '';
|
||||
toast(d.message, 'success');
|
||||
return d.result;
|
||||
}).then(function () { location.reload(); }).catch(function () {});
|
||||
}).then(function () { reloadInPlace(); }).catch(function () {});
|
||||
}
|
||||
function resendVerification() {
|
||||
api.action('/api/account/email/resend', {}).catch(function () {});
|
||||
|
||||
@@ -486,18 +486,23 @@
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// The last login in the browser's time, again after an in-place update (nav.js)
|
||||
function showLastLogin() {
|
||||
var el = document.getElementById('lastLogin');
|
||||
if (el) {
|
||||
var ts = parseInt(el.getAttribute('data-ts'));
|
||||
el.textContent = ts > 0 ? new Date(ts * 1000).toLocaleString() : 'Never';
|
||||
}
|
||||
}
|
||||
document.addEventListener('dash:refreshed', showLastLogin);
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
showLastLogin();
|
||||
var inventory = document.getElementById('inventoryModal');
|
||||
if (inventory) inventory.addEventListener('show.bs.modal', InventoryView.open, { once: true });
|
||||
});
|
||||
|
||||
var characterId = document.getElementById('restrictions').getAttribute('data-character-id');
|
||||
// Saves from the game (inventory, stats, level) and mail arrive live
|
||||
// Saves from the game (inventory, stats, level) and mail arrive live, updating the page in place
|
||||
if (window.Live) Live.refreshPage(['characters', 'mail'], characterId);
|
||||
|
||||
document.querySelectorAll('[data-restriction]').forEach(function (input) {
|
||||
@@ -741,7 +746,7 @@ function saveXml(confirmed) {
|
||||
if (!d.requestId) return;
|
||||
Live.waitForAction(d.requestId).then(function (r) {
|
||||
if (r.message) toast(r.message, r.success ? 'info' : 'danger');
|
||||
if (r.success) location.reload();
|
||||
if (r.success) reloadInPlace();
|
||||
});
|
||||
}).catch(function () {});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user