130 lines
3.8 KiB
JavaScript
130 lines
3.8 KiB
JavaScript
// 聊天室字号偏好控制,保留旧的 localStorage key 以兼容已有用户设置。
|
|
|
|
export const CHAT_FONT_SIZE_STORAGE_KEY = "chat_font_size";
|
|
export const CHAT_DEFAULT_FONT_SIZE = 13;
|
|
export const CHAT_FONT_SIZE_MIN = 10;
|
|
export const CHAT_FONT_SIZE_MAX = 30;
|
|
let fontSizeEventsBound = false;
|
|
|
|
/**
|
|
* 规整聊天室字号,过滤非法或越界的旧缓存值。
|
|
*
|
|
* @param {unknown} size 字号大小
|
|
* @returns {number|null}
|
|
*/
|
|
export function normalizeChatFontSize(size) {
|
|
const px = Number.parseInt(String(size ?? ""), 10);
|
|
|
|
if (Number.isNaN(px) || px < CHAT_FONT_SIZE_MIN || px > CHAT_FONT_SIZE_MAX) {
|
|
return null;
|
|
}
|
|
|
|
return px;
|
|
}
|
|
|
|
/**
|
|
* 同步底部输入框上方工具按钮字号。
|
|
*
|
|
* @param {number} px 用户选择的聊天字号
|
|
* @returns {void}
|
|
*/
|
|
function applyInputToolbarFontSize(px) {
|
|
const toolbarRow = document.querySelector("#chat-form > .input-row");
|
|
if (!(toolbarRow instanceof HTMLElement)) {
|
|
return;
|
|
}
|
|
|
|
const fontSize = `${px}px`;
|
|
toolbarRow.style.fontSize = fontSize;
|
|
toolbarRow.style.fontFamily = "inherit";
|
|
toolbarRow.style.lineHeight = "1.2";
|
|
toolbarRow.querySelectorAll([
|
|
":scope > label",
|
|
":scope > label select",
|
|
":scope > label input",
|
|
":scope > button",
|
|
":scope > div > button",
|
|
"#feature-menu button",
|
|
"#admin-menu button",
|
|
].join(",")).forEach((control) => {
|
|
control.style.fontFamily = "inherit";
|
|
control.style.fontSize = "inherit";
|
|
control.style.lineHeight = "1.2";
|
|
control.style.fontWeight = "400";
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 应用字号到聊天消息窗口和输入栏工具按钮,并保存到 localStorage。
|
|
*
|
|
* @param {string|number} size 字号大小
|
|
* @param {{syncContext?:boolean}} options 同步选项
|
|
* @returns {boolean}
|
|
*/
|
|
export function applyFontSize(size, options = {}) {
|
|
const px = normalizeChatFontSize(size);
|
|
if (px === null) {
|
|
return false;
|
|
}
|
|
|
|
const publicContainer = document.getElementById("chat-messages-container");
|
|
const privateContainer = document.getElementById("chat-messages-container2");
|
|
if (publicContainer) {
|
|
publicContainer.style.fontSize = `${px}px`;
|
|
}
|
|
if (privateContainer) {
|
|
privateContainer.style.fontSize = `${px}px`;
|
|
}
|
|
applyInputToolbarFontSize(px);
|
|
|
|
localStorage.setItem(CHAT_FONT_SIZE_STORAGE_KEY, String(px));
|
|
if (options.syncContext !== false && window.chatContext && typeof window.chatContext === "object") {
|
|
window.chatContext.chatPreferences = {
|
|
...(window.chatContext.chatPreferences || {}),
|
|
font_size: px,
|
|
};
|
|
}
|
|
|
|
const selector = document.getElementById("font_size_select");
|
|
if (selector) {
|
|
selector.value = String(px);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 从账号偏好或 localStorage 恢复已保存的聊天室字号。
|
|
*
|
|
* @returns {boolean}
|
|
*/
|
|
export function restoreChatFontSize() {
|
|
const serverFontSize = normalizeChatFontSize(window.chatContext?.chatPreferences?.font_size);
|
|
const localFontSize = normalizeChatFontSize(localStorage.getItem(CHAT_FONT_SIZE_STORAGE_KEY));
|
|
const saved = serverFontSize ?? localFontSize ?? CHAT_DEFAULT_FONT_SIZE;
|
|
|
|
return applyFontSize(saved, { syncContext: serverFontSize !== null });
|
|
}
|
|
|
|
/**
|
|
* 绑定字号选择器事件。
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
export function bindChatFontSizeControl() {
|
|
if (fontSizeEventsBound || typeof document === "undefined") {
|
|
return;
|
|
}
|
|
|
|
fontSizeEventsBound = true;
|
|
document.addEventListener("change", (event) => {
|
|
if (!(event.target instanceof HTMLSelectElement) || event.target.id !== "font_size_select") {
|
|
return;
|
|
}
|
|
|
|
if (applyFontSize(event.target.value)) {
|
|
void window.saveChatPreferences?.();
|
|
}
|
|
});
|
|
}
|