- enable the native Links manager and drop the custom friend-link option/REST path - add per-page link settings for the friends template - render link categories from get_bookmarks() with search and page-content options - add a validated public link submission endpoint with logo upload, captcha, rate limiting and duplicate checks - create pending links for review and notify administrators by email and in-app message - add native Links admin pending count, columns and edit notes - cover the new submission and cleanup contracts Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
88 lines
3.0 KiB
JavaScript
88 lines
3.0 KiB
JavaScript
/**
|
|
* Native link submission form.
|
|
*
|
|
* @package Jio
|
|
*/
|
|
(function () {
|
|
'use strict';
|
|
|
|
var cfg = window.jioLinksSubmit || {};
|
|
var i18n = cfg.i18n || {};
|
|
var form = document.querySelector('.jio-links-submit-form');
|
|
if (!form) return;
|
|
|
|
var button = form.querySelector('.jio-links-submit-btn');
|
|
var status = form.querySelector('.jio-links-submit-status');
|
|
var logoInput = form.querySelector('.jio-links-logo-input');
|
|
var preview = form.querySelector('.jio-links-logo-preview');
|
|
|
|
function setStatus(message, type) {
|
|
if (!status) return;
|
|
status.textContent = message || '';
|
|
status.className = 'jio-links-submit-status' + (type ? ' text-' + type : '');
|
|
}
|
|
|
|
if (logoInput && preview) {
|
|
logoInput.addEventListener('change', function () {
|
|
var file = logoInput.files && logoInput.files[0];
|
|
if (!file) return;
|
|
preview.src = URL.createObjectURL(file);
|
|
});
|
|
}
|
|
|
|
form.addEventListener('submit', function (event) {
|
|
event.preventDefault();
|
|
if (button && button.disabled) return;
|
|
|
|
var payload = new FormData(form);
|
|
var original = button ? button.innerHTML : '';
|
|
if (button) {
|
|
button.disabled = true;
|
|
button.innerHTML = '<i class="fa fas fa-spinner fa-spin"></i> ' + (i18n.submitting || '正在提交…');
|
|
}
|
|
setStatus(i18n.submitting || '正在提交…', 'muted');
|
|
|
|
var captcha = window.JioCaptcha;
|
|
var captchaPromise = captcha ? captcha.run('friend_link', form) : Promise.resolve({});
|
|
captchaPromise.then(function (tokens) {
|
|
if (tokens === null) throw new Error(i18n.captcha || '请完成人机验证');
|
|
Object.keys(tokens || {}).forEach(function (key) {
|
|
payload.set(key, tokens[key]);
|
|
});
|
|
return fetch(cfg.ajaxUrl || '/wp-admin/admin-ajax.php', {
|
|
method: 'POST',
|
|
credentials: 'same-origin',
|
|
body: payload,
|
|
});
|
|
}).then(function (response) {
|
|
return response.json().then(function (body) {
|
|
return { ok: response.ok, body: body };
|
|
});
|
|
}).then(function (result) {
|
|
var body = result.body || {};
|
|
var data = body.data || {};
|
|
if (!result.ok || !body.success) {
|
|
throw new Error(data.message || i18n.error || '提交失败,请重试');
|
|
}
|
|
setStatus(data.message || i18n.success || '提交成功', 'success');
|
|
form.reset();
|
|
if (preview) preview.src = '';
|
|
if (button) button.disabled = false;
|
|
if (button) button.innerHTML = original;
|
|
if (captcha) captcha.reset('friend_link', form);
|
|
window.setTimeout(function () {
|
|
var modal = document.getElementById('submit-links-modal');
|
|
if (modal) modal.classList.remove('show', 'is-open');
|
|
setStatus('', '');
|
|
}, 1800);
|
|
}).catch(function (error) {
|
|
setStatus(error.message || i18n.error || '提交失败,请重试', 'danger');
|
|
if (button) {
|
|
button.disabled = false;
|
|
button.innerHTML = original;
|
|
}
|
|
if (captcha) captcha.reset('friend_link', form);
|
|
});
|
|
});
|
|
})();
|