总会会长 🍭', isModerator: true, moderatorCategory: '' },
{ name: '神墨网络', username: 'SMNET', avatar: '/user_avatar/linux.do/smnet/96/95935_2.png', description: '🐾 护猫使者 🐾', isModerator: true, moderatorCategory: '' }
];
const defaultEmotionalState = [
'容光焕发', '无精打采', '精神抖擞', '奄奄一息', '气宇轩昂',
'疲惫不堪', '落落大方', '愁眉苦脸', '满面春风', '心力交瘁',
'风度翩翩', '萎靡不振', '温文尔雅', '怏怏不乐', '精神焕发',
'人见人爱,花见花开,车见车爆胎'
];
let config = {
enableRandomUser: GM_getValue('enableRandomUser', true),
enableSignature: GM_getValue('enableSignature', true),
enableMinCharCompletion: GM_getValue('enableMinCharCompletion', true),
closeConfigAfterSave: GM_getValue('closeConfigAfterSave', true),
anyoneSay: updateOldConfig(GM_getValue('anyoneSay', defaultAnyoneSay)),
emotionalState: GM_getValue('emotionalState', defaultEmotionalState)
};
const randInt = (start, end) => {
return Math.floor(Math.random() * (end - start + 1)) + start;
};
const getEmotionalState = () => {
return config.emotionalState[randInt(0, config.emotionalState.length - 1)];
};
function updateOldConfig(oldConfig) {
return oldConfig.map(user => ({
...user,
isModerator: user.isModerator || false,
moderatorCategory: user.moderatorCategory || ''
}));
}
// 获取预加载数据
function getPreloadedData() {
const preloadedDataElement = document.querySelector("#data-preloaded");
if (!preloadedDataElement) {
throw new Error("Preloaded data element not found");
}
const preloadedData = preloadedDataElement.getAttribute("data-preloaded");
return JSON.parse(preloadedData);
};
// 获取用户名
function getUsername() {
const preloadedData = getPreloadedData();
const preloadedCurrentUserData = JSON.parse(preloadedData.currentUser);
return preloadedCurrentUserData.username;
}
function getCategoryNames() {
const categories = [];
// 第一种方式
const titleWrapper = document.getElementsByClassName('title-wrapper')[0];
if (titleWrapper && titleWrapper.children[1]) {
for (let child of titleWrapper.children[1].children) {
if (child.children[0]) {
categories.push(child.children[0].innerText.trim());
}
}
}
// 第二种方式
const topicCategory = document.getElementsByClassName('topic-category')[0];
if (topicCategory) {
categories.push(...topicCategory.innerText.split('\n').map(cat => cat.trim()));
}
return categories;
}
function isSecretGarden() {
const categories = getCategoryNames();
return categories.includes("秘密花园");
}
function isCategoryMatch(userCategory, pageCategories) {
if (!userCategory) return true; // 如果用户没有指定类别,则认为匹配
return pageCategories.some(category => category === userCategory);
}
function getRandomUser() {
const randomUser = config.anyoneSay[Math.floor(Math.random() * config.anyoneSay.length)];
const pageCategories = getCategoryNames();
const isModerator = randomUser.isModerator && isCategoryMatch(randomUser.moderatorCategory, pageCategories);
let userHtml = `
`;
// 添加名称,总是带颜色
userHtml += isModerator ? `[color=#00aeff]**${randomUser.name}**[/color] ` : `${randomUser.name} `;
// 如果是版主,添加版主图标
if (isModerator) {
userHtml += `
`;
}
// 如果用户名和名称不同,则添加用户名
userHtml += randomUser.name !== randomUser.username ? `${randomUser.username} ` : '';
// 添加描述和表情
userHtml += `[color=#919191]${randomUser.description}[/color]
\n `;
return userHtml;
}
function handleClick(event) {
if (event.target && event.target.closest('button.create')) {
processTextarea();
}
}
function handleKeydown(event) {
if (event.ctrlKey && event.key === 'Enter') {
processTextarea();
}
}
function processTextarea() {
if (!isSecretGarden()) { return; }
let textarea = document.querySelector('#reply-control textarea');
let text = textarea.value.trim();
let originalLength = text.length;
if (text.length !== 0) {
if (config.enableRandomUser && !text.includes("eHs0oDRBVpTk7yaAQJ7zxxDnDrv.png")) {
text = getRandomUser() + text;
}
let signature = `${getUsername()}`;
if (config.enableSignature && !text.includes(signature)) {
text = `${text}\n\n---\n\n— 来自${getEmotionalState()}的 ${signature}
`;
}
if (config.enableMinCharCompletion && originalLength < MIN_REQUIRED_CHARS) {
// 通过添加零宽字符来补足长度到最小要求
while (text.length < MIN_REQUIRED_CHARS) {
text += ZERO_WIDTH_SPACE;
}
}
textarea.value = text;
// 创建并触发 input 事件
const inputEvent = new Event('input', {
bubbles: true,
cancelable: true
});
// 触发事件
textarea.dispatchEvent(inputEvent);
}
}
function createConfigPanel() {
const panel = document.createElement('div');
panel.id = 'feisay-config-panel';
panel.style.position = 'fixed';
panel.style.top = '80px';
panel.style.right = '360px';
panel.style.padding = '20px';
panel.style.border = `1px solid var(--panel-border)`;
panel.style.borderRadius = '8px';
panel.style.zIndex = '10000';
panel.style.width = '300px';
panel.style.maxHeight = '80%';
panel.style.overflowY = 'auto';
panel.style.display = 'none'; // 默认隐藏面板
panel.style.backgroundColor = 'var(--panel-bg)';
panel.style.color = 'var(--panel-text)';
panel.style.boxShadow = '0 4px 6px rgba(0, 0, 0, 0.1)';
const title = document.createElement('h3');
title.textContent = '斐说配置';
title.style.marginTop = '0';
title.style.marginBottom = '15px';
panel.appendChild(title);
const createCheckbox = (id, text, checked) => {
const label = document.createElement('label');
label.style.display = 'flex';
label.style.alignItems = 'center';
label.style.marginBottom = '10px';
label.style.cursor = 'pointer';
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = id;
checkbox.checked = checked;
checkbox.style.marginRight = '10px';
checkbox.addEventListener('change', (e) => {
config[id] = e.target.checked;
GM_setValue(id, config[id]);
});
label.appendChild(checkbox);
label.appendChild(document.createTextNode(text));
return label;
};
panel.appendChild(createCheckbox('enableRandomUser', '启用随机用户头像和名称', config.enableRandomUser));
panel.appendChild(createCheckbox('enableSignature', '启用末尾签名', config.enableSignature));
panel.appendChild(createCheckbox('enableMinCharCompletion', '启用最小字符数补全', config.enableMinCharCompletion));
panel.appendChild(createCheckbox('closeConfigAfterSave', '保存后自动关闭配置页面', config.closeConfigAfterSave));
const createTextArea = (id, value, placeholder) => {
const container = document.createElement('div');
container.style.marginBottom = '15px';
const label = document.createElement('label');
label.textContent = placeholder;
label.style.display = 'block';
label.style.marginBottom = '5px';
container.appendChild(label);
const textarea = document.createElement('textarea');
textarea.id = id;
textarea.value = JSON.stringify(value, null, 2);
textarea.rows = 5;
textarea.style.width = '100%';
textarea.style.padding = '5px';
textarea.style.border = '1px solid var(--panel-border)';
textarea.style.borderRadius = '4px';
textarea.style.backgroundColor = 'var(--panel-bg)';
textarea.style.color = 'var(--panel-text)';
container.appendChild(textarea);
return container;
};
panel.appendChild(createTextArea('anyoneSay', config.anyoneSay, '自定义用户列表:'));
panel.appendChild(createTextArea('emotionalState', config.emotionalState, '自定义情绪状态:'));
const buttonContainer = document.createElement('div');
buttonContainer.style.display = 'flex';
buttonContainer.style.justifyContent = 'space-between';
const createButton = (text, onClick, primary = false) => {
const button = document.createElement('button');
button.textContent = text;
button.style.padding = '8px 16px';
button.style.border = 'none';
button.style.borderRadius = '4px';
button.style.cursor = 'pointer';
button.style.backgroundColor = primary ? '#0078d7' : '#f0f0f0';
button.style.color = primary ? '#ffffff' : '#333333';
button.addEventListener('click', onClick);
return button;
};
const saveButton = createButton('保存设置', () => {
try {
const newAnyoneSay = JSON.parse(document.getElementById('anyoneSay').value);
config.anyoneSay = updateOldConfig(newAnyoneSay);
config.emotionalState = JSON.parse(document.getElementById('emotionalState').value);
GM_setValue('anyoneSay', config.anyoneSay);
GM_setValue('emotionalState', config.emotionalState);
if (config.closeConfigAfterSave) {
panel.style.display = 'none';
}
} catch (error) {
alert('保存失败,请检查输入格式是否正确');
}
}, true);
const closeButton = createButton('关闭', () => {
panel.style.display = 'none';
});
buttonContainer.appendChild(saveButton);
buttonContainer.appendChild(closeButton);
panel.appendChild(buttonContainer);
document.body.appendChild(panel);
return panel;
}
function toggleConfigPanel() {
const panel = document.getElementById('feisay-config-panel') || createConfigPanel();
panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
}
function createConfigButton() {
const toolbar = document.querySelector('.d-editor-button-bar');
if (!toolbar || document.querySelector('.feisay-config')) return;
const configButton = document.createElement('button');
configButton.className = 'btn btn-flat btn-icon no-text user-menu-tab active feisay-config';
configButton.title = '斐说配置';
configButton.innerHTML = ' ';
configButton.onclick = toggleConfigPanel;
toolbar.appendChild(configButton);
}
function watchReplyControl() {
const replyControl = document.getElementById('reply-control');
if (!replyControl) return;
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
if (replyControl.classList.contains('closed')) {
const panel = document.getElementById('feisay-config-panel');
if (panel) {
panel.style.display = 'none';
}
} else {
// 当 reply-control 重新打开时,尝试添加配置按钮
setTimeout(() => {
if (!document.querySelector('.feisay-config')) {
createConfigButton();
}
}, 500); // 给予一些时间让编辑器完全加载
}
}
});
});
observer.observe(replyControl, { attributes: true });
}
function watchForEditor() {
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList') {
const addedNodes = mutation.addedNodes;
for (let node of addedNodes) {
if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains('d-editor')) {
if (!document.querySelector('.feisay-config')) {
createConfigButton();
}
return;
}
}
}
});
});
observer.observe(document.body, { childList: true, subtree: true });
}
function init() {
const container = document.getElementById("reply-control");
container.addEventListener('click', handleClick, true);
document.addEventListener('keydown', handleKeydown, true);
if (!document.querySelector('.feisay-config')) {
createConfigButton();
}
watchReplyControl();
watchForEditor();
}
// 初始化
setTimeout(() => init(), 1000);
})();