用户公开主页全局采用DOM无刷新加载

This commit is contained in:
2026-08-23 14:55:24 +08:00
parent c3f66e9a14
commit bb9a410ad6
14 changed files with 569 additions and 231 deletions
+77 -21
View File
@@ -1,26 +1,22 @@
/**
* AKSRT Public User Home runtime
*
* Handles public user-home dashboard tabs and cover uploads.
* Loaded on /user/{nicename}/ (author archives 301-redirect here).
* Handles public user-home dashboard tabs, panel fragment loading and cover
* uploads. The URL stays clean (/author/{name}/) — tabs, follow sub-tabs and
* pagination are loaded via the aksrt/v1 user-home panel REST fragment.
*
* @package AKSRT
*/
/* global aksrtAuthorPage */
/* global aksrtAuthorPage, aksrtData, AksrtFrontend, notyf */
(function () {
'use strict';
function updateTabUrl(root, name, defaultTab) {
if (!window.history || typeof window.history.replaceState !== 'function') return;
var url = new URL(window.location.href);
if (!name || name === defaultTab) {
url.searchParams.delete('tab');
} else {
url.searchParams.set('tab', name);
function notifyLoadError() {
if (typeof notyf === 'function') {
notyf('加载失败,请重试', 'danger');
}
window.history.replaceState({}, '', url.toString());
}
function initPublicDashboards() {
@@ -32,6 +28,7 @@
if (!tabs.length) return;
var defaultTab = root.dataset.defaultTab || tabs[0].getAttribute('data-tab') || 'posts';
var userId = parseInt(root.dataset.userId || '0', 10);
var panels = {};
tabs.forEach(function (tab) {
@@ -45,7 +42,7 @@
}
});
function switchTo(name, syncUrl) {
function switchTo(name) {
if (!panels[name]) {
name = defaultTab;
}
@@ -61,24 +58,83 @@
panels[key].panel.setAttribute('hidden', '');
}
});
if (syncUrl) {
updateTabUrl(root, name, defaultTab);
}
}
function resolveInitialTab() {
var url = new URL(window.location.href);
return url.searchParams.get('tab') || defaultTab;
function loadPanelBody(panel, name, page, sub) {
var cfg = window.aksrtData || {};
var restBase = cfg.apiUrl || cfg.restUrl || '';
if (!userId || !restBase) return Promise.reject(new Error('rest-unavailable'));
if (panel._aksrtUhRequest) return panel._aksrtUhRequest;
var followSub = sub || panel.dataset.uhSub || 'followers';
panel.dataset.uhPage = String(page);
panel.dataset.uhSub = followSub;
panel.classList.add('is-loading');
var url = restBase.replace(/\/$/, '') + '/user-home/panel/' + userId + '/' + encodeURIComponent(name)
+ '?page=' + encodeURIComponent(page) + '&sub=' + encodeURIComponent(followSub);
panel._aksrtUhRequest = fetch(url, {
credentials: 'same-origin',
headers: {
'X-WP-Nonce': cfg.restNonce || cfg.nonce || ''
}
}).then(function (response) {
return response.json().then(function (payload) {
if (!response.ok || !payload || !payload.success || !payload.data || typeof payload.data.html !== 'string') {
throw new Error('panel-load-failed');
}
panel.innerHTML = payload.data.html;
if (window.AksrtFrontend && typeof window.AksrtFrontend.rehydrate === 'function') {
window.AksrtFrontend.rehydrate(panel, 'ajax');
}
});
}).finally(function () {
panel._aksrtUhRequest = null;
panel.classList.remove('is-loading');
});
return panel._aksrtUhRequest;
}
function panelNameOf(panel) {
var name = (panel.id || '').replace(/^panel-/, '');
return panels[name] ? name : '';
}
tabs.forEach(function (tab) {
tab.addEventListener('click', function () {
switchTo(tab.getAttribute('data-tab'), true);
switchTo(tab.getAttribute('data-tab'));
});
});
switchTo(resolveInitialTab(), false);
// Delegate sub-tab / pagination clicks so buttons injected by REST
// fragments keep working without rebinding.
root.addEventListener('click', function (event) {
var target = event.target && event.target.closest ? event.target : null;
if (!target) return;
var subBtn = target.closest('[data-uh-sub]');
if (subBtn) {
event.preventDefault();
var followPanel = subBtn.closest('.dashboard-panel');
if (!followPanel) return;
var sub = subBtn.getAttribute('data-uh-sub') === 'following' ? 'following' : 'followers';
loadPanelBody(followPanel, 'follow', 1, sub).catch(notifyLoadError);
return;
}
var pageBtn = target.closest('[data-uh-page]');
if (!pageBtn) return;
event.preventDefault();
var panel = pageBtn.closest('.dashboard-panel');
if (!panel) return;
var name = panelNameOf(panel);
if (!name) return;
var page = Math.max(1, parseInt(pageBtn.getAttribute('data-uh-page') || '1', 10) || 1);
loadPanelBody(panel, name, page, panel.dataset.uhSub || 'followers').catch(notifyLoadError);
});
switchTo(defaultTab);
});
}