补充中文语言包

This commit is contained in:
feibisi 2025-06-24 11:50:33 +08:00
parent 0ecad06f54
commit 836b293850
18 changed files with 5061 additions and 2398 deletions

235
assets/dashboard-core.js Normal file
View file

@ -0,0 +1,235 @@
jQuery(document).ready(function($) {
'use strict';
const MSD_Core = {
refreshInterval: null,
refreshRate: 300000,
isRefreshing: false,
retryCount: 0,
maxRetries: 3,
init() {
this.bindEvents();
this.startAutoRefresh();
this.setupErrorHandling();
},
bindEvents() {
$(document)
.on('click', '.msd-refresh-btn', this.handleRefreshClick.bind(this));
$(window).on('beforeunload', () => {
if (this.refreshInterval) {
clearInterval(this.refreshInterval);
}
});
},
setupErrorHandling() {
$(document).ajaxError((event, xhr, settings, error) => {
if (settings.url && settings.url.includes('msd_')) {
console.error('MSD Ajax Error:', error, xhr);
this.showNotice(msdAjax.strings.error_occurred, 'error');
}
});
},
startAutoRefresh() {
this.refreshInterval = setInterval(() => {
if (!this.isRefreshing && document.visibilityState === 'visible') {
if (window.MSD_Widgets && window.MSD_Widgets.loadAllWidgets) {
window.MSD_Widgets.loadAllWidgets();
}
}
}, this.refreshRate);
},
handleRefreshClick(e) {
e.preventDefault();
const $btn = $(e.currentTarget);
const widgetType = $btn.data('widget');
if ($btn.hasClass('refreshing')) return;
$btn.addClass('refreshing').prop('disabled', true);
setTimeout(() => {
$btn.removeClass('refreshing').prop('disabled', false);
}, 2000);
if (widgetType && window.MSD_Widgets) {
window.MSD_Widgets.loadWidget(widgetType);
this.showNotice(msdAjax.strings.refresh_success, 'success', 2000);
} else if (window.MSD_Widgets) {
window.MSD_Widgets.loadAllWidgets();
this.showNotice(msdAjax.strings.refresh_success, 'success', 2000);
}
},
makeAjaxRequest(action, data, successCallback, errorCallback) {
const ajaxData = {
action: action,
nonce: msdAjax.nonce,
...data
};
return $.post(msdAjax.ajaxurl, ajaxData)
.done((response) => {
if (response.success) {
successCallback(response);
} else {
errorCallback(response.data || 'Unknown error');
}
})
.fail((xhr, status, error) => {
errorCallback(error);
});
},
showNotice(message, type = 'info', duration = 5000) {
const $notice = $(`<div class="msd-notice ${type}"><p>${this.escapeHtml(message)}</p></div>`);
const $container = $('.wrap h1').first();
if ($container.length) {
$container.after($notice);
} else {
$('body').prepend($notice);
}
if (duration > 0) {
setTimeout(() => {
$notice.fadeOut(300, () => $notice.remove());
}, duration);
}
$notice.on('click', () => {
$notice.fadeOut(300, () => $notice.remove());
});
},
formatNumber(num) {
if (num >= 1000000) {
return (num / 1000000).toFixed(1) + 'M';
} else if (num >= 1000) {
return (num / 1000).toFixed(1) + 'K';
}
return num.toString();
},
formatTime(date) {
return date.toLocaleTimeString([], {
hour: '2-digit',
minute: '2-digit'
});
},
escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
},
decodeHtmlEntities(text) {
const textarea = document.createElement('textarea');
textarea.innerHTML = text;
return textarea.value;
},
truncateText(text, maxLength) {
if (!text || text.length <= maxLength) {
return text;
}
return text.substring(0, maxLength).trim() + '...';
},
isValidUrl(string) {
try {
const url = new URL(string);
return url.protocol === 'http:' || url.protocol === 'https:';
} catch (_) {
return false;
}
},
getStorageStatusClass(status) {
const statusMap = {
critical: 'critical',
warning: 'warning',
good: '',
default: ''
};
return statusMap[status] || statusMap.default;
},
getDefaultFavicon() {
return 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgdmlld0JveD0iMCAwIDMyIDMyIj48cmVjdCB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIGZpbGw9IiNmMGYwZjAiLz48dGV4dCB4PSI1MCUiIHk9IjUwJSIgZm9udC1mYW1pbHk9IkFyaWFsLCBzYW5zLXNlcmlmIiBmb250LXNpemU9IjEyIiBmaWxsPSIjOTk5IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBkeT0iMC4zNWVtIj5TPC90ZXh0Pjwvc3ZnPg==';
},
getDefaultAvatar() {
return 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgdmlld0JveD0iMCAwIDQwIDQwIj48Y2lyY2xlIGN4PSIyMCIgY3k9IjIwIiByPSIyMCIgZmlsbD0iI2Y2ZjdmNyIgc3Ryb2tlPSIjZGRkIi8+PGNpcmNsZSBjeD0iMjAiIGN5PSIxNSIgcj0iNiIgZmlsbD0iIzk5OSIvPjxlbGxpcHNlIGN4PSIyMCIgY3k9IjMzIiByeD0iMTAiIHJ5PSI3IiBmaWxsPSIjOTk5Ii8+PC9zdmc+';
},
formatNewsDate(dateString) {
try {
const date = new Date(dateString);
const now = new Date();
const diffTime = Math.abs(now - date);
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
if (diffDays === 1) {
return 'Yesterday';
} else if (diffDays < 7) {
return `${diffDays} days ago`;
} else {
return date.toLocaleDateString();
}
} catch (e) {
return '';
}
},
getUserStatusClass(status) {
const statusMap = {
'active': 'good',
'recent': 'good',
'inactive': 'warning',
'very_inactive': 'critical',
'never_logged_in': 'neutral'
};
return statusMap[status] || 'neutral';
},
getUserStatusLabel(status) {
const statusLabels = {
'active': 'Active',
'recent': 'Recent',
'inactive': 'Inactive',
'very_inactive': 'Very Inactive',
'never_logged_in': 'Never Logged In'
};
return statusLabels[status] || 'Unknown';
},
getRegistrationLabel(registration) {
const labels = {
'none': 'Disabled',
'user': 'Users Only',
'blog': 'Sites Only',
'all': 'Users & Sites'
};
return labels[registration] || 'Unknown';
}
};
window.MSD_Core = MSD_Core;
MSD_Core.init();
$('head').append(`
<style>
body.modal-open { overflow: hidden; }
.msd-refresh-btn.refreshing { opacity: 0.6; pointer-events: none; }
.msd-error-state { text-align: center; padding: 20px; color: var(--msd-text-light); }
.msd-emoji-icon { font-size: 18px !important; display: inline-block; filter: grayscale(55%); }
</style>
`);
});

376
assets/dashboard-modals.js Normal file
View file

@ -0,0 +1,376 @@
jQuery(document).ready(function($) {
'use strict';
const MSD_Modals = {
init() {
this.bindEvents();
// 延迟初始化 sortable等待页面完全加载
$(document).ready(() => {
setTimeout(() => {
this.initSortable();
}, 1000);
});
},
bindEvents() {
$(document)
.on('click', '#msd-add-link', this.addQuickLinkRow.bind(this))
.on('click', '.msd-remove-link', this.removeQuickLinkRow.bind(this))
.on('click', '#msd-add-news-source', this.addNewsSourceRow.bind(this))
.on('click', '.msd-remove-source', this.removeNewsSourceRow.bind(this))
.on('click', '.msd-modal-close, .msd-modal', this.handleModalClose.bind(this))
.on('click', '.msd-modal-content', function(e) { e.stopPropagation(); })
.on('click', '.msd-news-settings button', this.showNewsSourcesModal.bind(this));
window.MSD = {
showQuickLinksModal: this.showQuickLinksModal.bind(this),
hideQuickLinksModal: this.hideQuickLinksModal.bind(this),
saveQuickLinks: this.saveQuickLinks.bind(this),
showNewsSourcesModal: this.showNewsSourcesModal.bind(this),
hideNewsSourcesModal: this.hideNewsSourcesModal.bind(this),
saveNewsSources: this.saveNewsSources.bind(this),
showContactInfoModal: this.showContactInfoModal.bind(this),
hideContactInfoModal: this.hideContactInfoModal.bind(this),
saveContactInfo: this.saveContactInfo.bind(this),
selectQRImage: this.selectQRImage.bind(this),
removeQRCode: this.removeQRCode.bind(this),
clearNewsCache: this.clearNewsCache.bind(this)
};
},
initSortable() {
// 使用延迟初始化确保DOM元素存在
$(document).ready(() => {
setTimeout(() => {
if ($.ui && $.ui.sortable && $('#msd-sortable-links').length && !$('#msd-sortable-links').hasClass('ui-sortable')) {
$('#msd-sortable-links').sortable({
tolerance: 'pointer',
cursor: 'move',
placeholder: 'ui-sortable-placeholder',
helper: function(e, ui) {
ui.addClass('ui-sortable-helper');
return ui;
},
stop: (event, ui) => {
this.saveQuickLinksOrder();
}
});
}
}, 500);
});
},
saveQuickLinksOrder() {
const order = [];
$('#msd-sortable-links .msd-quick-link-item').each(function() {
const index = $(this).data('index');
if (index !== undefined) {
order.push(index);
}
});
if (order.length > 0 && window.MSD_Core) {
window.MSD_Core.makeAjaxRequest('msd_reorder_quick_links', { order },
() => {
window.MSD_Core.showNotice(msdAjax.strings.save_success, 'success', 2000);
},
() => {
window.MSD_Core.showNotice('Failed to save order', 'error');
}
);
}
},
handleModalClose(e) {
if (e.target === e.currentTarget || $(e.target).hasClass('msd-modal-close')) {
this.hideQuickLinksModal();
this.hideNewsSourcesModal();
this.hideContactInfoModal();
}
},
showQuickLinksModal() {
$('#msd-quick-links-modal').fadeIn(200);
$('body').addClass('modal-open');
},
hideQuickLinksModal() {
$('#msd-quick-links-modal').fadeOut(200);
$('body').removeClass('modal-open');
},
showNewsSourcesModal() {
$('#msd-news-sources-modal').fadeIn(200);
$('body').addClass('modal-open');
},
hideNewsSourcesModal() {
$('#msd-news-sources-modal').fadeOut(200);
$('body').removeClass('modal-open');
},
showContactInfoModal() {
$('#msd-contact-info-modal').fadeIn(200);
$('body').addClass('modal-open');
},
hideContactInfoModal() {
$('#msd-contact-info-modal').fadeOut(200);
$('body').removeClass('modal-open');
},
addQuickLinkRow() {
const html = `
<div class="msd-link-item">
<div class="msd-link-row">
<input type="text" placeholder="Link Title" class="msd-link-title" required>
<input type="url" placeholder="https://example.com" class="msd-link-url" required>
</div>
<div class="msd-link-options">
<input type="text" placeholder="dashicons-admin-home or 🏠" class="msd-link-icon">
<label class="msd-checkbox-label">
<input type="checkbox" class="msd-link-newtab">
Open in new tab
</label>
<button type="button" class="msd-remove-link">Remove</button>
</div>
</div>
`;
$('#msd-quick-links-editor').append(html);
},
removeQuickLinkRow(e) {
$(e.currentTarget).closest('.msd-link-item').fadeOut(200, function() {
$(this).remove();
});
},
addNewsSourceRow() {
const html = `
<div class="msd-news-source-item">
<div class="msd-source-row">
<input type="text" placeholder="Source Name" class="msd-news-name" required>
<input type="url" placeholder="RSS Feed URL" class="msd-news-url" required>
</div>
<div class="msd-source-options">
<label class="msd-checkbox-label">
<input type="checkbox" class="msd-news-enabled" checked>
Enabled
</label>
<button type="button" class="msd-remove-source">Remove</button>
</div>
</div>
`;
$('#msd-news-sources-editor').append(html);
},
removeNewsSourceRow(e) {
$(e.currentTarget).closest('.msd-news-source-item').fadeOut(200, function() {
$(this).remove();
});
},
saveQuickLinks() {
const links = [];
let hasErrors = false;
// Clear previous errors
$('.msd-link-item').removeClass('error');
$('.msd-link-url').removeClass('error');
$('.msd-link-item').each(function() {
const $item = $(this);
const title = $item.find('.msd-link-title').val().trim();
const url = $item.find('.msd-link-url').val().trim();
const icon = $item.find('.msd-link-icon').val().trim();
const newTab = $item.find('.msd-link-newtab').is(':checked');
if (title && url) {
if (!MSD_Modals.isValidUrl(url)) {
$item.find('.msd-link-url').addClass('error');
hasErrors = true;
return;
}
$item.find('.msd-link-url').removeClass('error');
links.push({ title, url, icon, new_tab: newTab });
} else if (title || url) {
$item.addClass('error');
hasErrors = true;
}
});
if (hasErrors) {
if (window.MSD_Core) {
window.MSD_Core.showNotice('Please fill in all required fields correctly', 'error');
}
return;
}
// Disable the save button to prevent double submission
const $saveBtn = $('.msd-modal-footer .button-primary');
$saveBtn.prop('disabled', true).text('Saving...');
if (window.MSD_Core) {
window.MSD_Core.makeAjaxRequest('msd_save_quick_links', { links }, (response) => {
window.MSD_Core.showNotice(response.data.message, 'success');
this.hideQuickLinksModal();
setTimeout(() => location.reload(), 1000);
}, (error) => {
window.MSD_Core.showNotice('Failed to save quick links', 'error');
$saveBtn.prop('disabled', false).text('Save Links');
});
}
},
saveNewsSources() {
const sources = [];
let hasErrors = false;
// Clear previous errors
$('.msd-news-source-item').removeClass('error');
$('.msd-news-url').removeClass('error');
$('.msd-news-source-item').each(function() {
const $item = $(this);
const name = $item.find('.msd-news-name').val().trim();
const url = $item.find('.msd-news-url').val().trim();
const enabled = $item.find('.msd-news-enabled').is(':checked');
if (name && url) {
if (!MSD_Modals.isValidUrl(url)) {
$item.find('.msd-news-url').addClass('error');
hasErrors = true;
return;
}
$item.find('.msd-news-url').removeClass('error');
sources.push({ name, url, enabled });
} else if (name || url) {
$item.addClass('error');
hasErrors = true;
}
});
if (hasErrors) {
if (window.MSD_Core) {
window.MSD_Core.showNotice('Please fill in all required fields correctly', 'error');
}
return;
}
// Disable the save button to prevent double submission
const $saveBtn = $('#msd-news-sources-modal .button-primary');
$saveBtn.prop('disabled', true).text('Saving...');
if (window.MSD_Core) {
window.MSD_Core.makeAjaxRequest('msd_save_news_sources', { sources }, (response) => {
window.MSD_Core.showNotice(response.data.message, 'success');
this.hideNewsSourcesModal();
if (window.MSD_Widgets) {
window.MSD_Widgets.loadWidget('custom_news');
}
}, (error) => {
window.MSD_Core.showNotice('Failed to save news sources', 'error');
$saveBtn.prop('disabled', false).text('Save News Sources');
});
}
},
saveContactInfo() {
const contactInfo = {
name: $('#msd-contact-name').val().trim(),
email: $('#msd-contact-email').val().trim(),
phone: $('#msd-contact-phone').val().trim(),
website: $('#msd-contact-website').val().trim(),
description: $('#msd-contact-description').val().trim(),
qq: $('#msd-contact-qq').val().trim(),
wechat: $('#msd-contact-wechat').val().trim(),
whatsapp: $('#msd-contact-whatsapp').val().trim(),
telegram: $('#msd-contact-telegram').val().trim(),
qr_code: $('#msd-contact-qr-code').val().trim()
};
if (!contactInfo.name || !contactInfo.email) {
if (window.MSD_Core) {
window.MSD_Core.showNotice('Name and email are required', 'error');
}
return;
}
// Disable the save button to prevent double submission
const $saveBtn = $('#msd-contact-info-modal .button-primary');
$saveBtn.prop('disabled', true).text('Saving...');
if (window.MSD_Core) {
window.MSD_Core.makeAjaxRequest('msd_save_contact_info', contactInfo, (response) => {
window.MSD_Core.showNotice(response.data.message, 'success');
this.hideContactInfoModal();
setTimeout(() => location.reload(), 1000);
}, (error) => {
window.MSD_Core.showNotice('Failed to save contact information', 'error');
$saveBtn.prop('disabled', false).text('Save Contact Info');
});
}
},
selectQRImage() {
if (wp && wp.media) {
const frame = wp.media({
title: 'Select QR Code Image',
button: { text: 'Use Image' },
multiple: false
});
frame.on('select', function() {
const attachment = frame.state().get('selection').first().toJSON();
$('#msd-contact-qr-code').val(attachment.url);
$('#msd-qr-preview img').attr('src', attachment.url);
$('#msd-qr-preview').show();
});
frame.open();
} else {
const url = prompt('Enter QR code image URL:');
if (url) {
$('#msd-contact-qr-code').val(url);
$('#msd-qr-preview img').attr('src', url);
$('#msd-qr-preview').show();
}
}
},
removeQRCode() {
$('#msd-contact-qr-code').val('');
$('#msd-qr-preview').hide();
},
clearNewsCache() {
if (window.MSD_Core) {
window.MSD_Core.makeAjaxRequest('msd_refresh_widget_data', { widget: 'custom_news' }, (response) => {
window.MSD_Core.showNotice('News cache cleared successfully', 'success');
if (window.MSD_Widgets) {
window.MSD_Widgets.loadWidget('custom_news');
}
}, (error) => {
window.MSD_Core.showNotice('Failed to clear news cache', 'error');
});
}
},
isValidUrl(string) {
if (window.MSD_Core && window.MSD_Core.isValidUrl) {
return window.MSD_Core.isValidUrl(string);
}
try {
const url = new URL(string);
return url.protocol === 'http:' || url.protocol === 'https:';
} catch (_) {
return false;
}
}
};
window.MSD_Modals = MSD_Modals;
MSD_Modals.init();
});

File diff suppressed because it is too large Load diff

View file

@ -1634,8 +1634,8 @@ div#network_dashboard_right_now .inside {
.msd-widget-toggle .description {
margin: 0;
font-size: 13px;
color: var(--msd-text-light);
font-size: 11px;
color: #8c8c8c;
line-height: 1.4;
}
@ -1869,3 +1869,33 @@ body.modal-open {
display: inline-block;
filter: grayscale(55%);
}
.msd-update-notice {
display: flex;
align-items: center;
gap: 8px;
padding: 8px;
margin-bottom: var(--msd-spacing);
background: #fff3cd;
border: 1px solid #ffeaa7;
border-radius: var(--msd-radius-small);
color: #856404;
font-size: 13px;
font-weight: 500;
}
.msd-update-notice .dashicons {
color: #dba617;
font-size: 16px;
line-height: 1.2;
}
.msd-update-link {
color: var(--msd-primary);
text-decoration: none;
font-weight: 500;
}
.msd-update-link:hover {
text-decoration: underline;
}