146 lines
4.4 KiB
JavaScript
146 lines
4.4 KiB
JavaScript
// 头像选择与个人设置弹窗事件绑定,替代 toolbar 中的内联 onclick/onchange。
|
|
|
|
let profileControlEventsBound = false;
|
|
|
|
/**
|
|
* 触发存量全局函数,保持当前头像与设置业务逻辑不变。
|
|
*
|
|
* @param {string} functionName 全局函数名
|
|
* @param {...unknown} args 参数
|
|
* @returns {void}
|
|
*/
|
|
function callGlobal(functionName, ...args) {
|
|
// 头像与设置的大段业务仍在 Blade 内,模块阶段先集中桥接旧全局函数。
|
|
if (typeof window[functionName] === "function") {
|
|
window[functionName](...args);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 处理动态头像项选择。
|
|
* 头像列表由 Blade 旧脚本异步生成,Vite 模块只通过 data-avatar-file 接管点击入口。
|
|
*
|
|
* @param {Element} target 点击目标
|
|
* @returns {boolean}
|
|
*/
|
|
function handleAvatarOptionClick(target) {
|
|
const avatarOption = target.closest("[data-avatar-file]");
|
|
if (!(avatarOption instanceof HTMLElement)) {
|
|
return false;
|
|
}
|
|
|
|
const file = avatarOption.getAttribute("data-avatar-file") || "";
|
|
if (!file) {
|
|
return false;
|
|
}
|
|
|
|
callGlobal("selectAvatar", file, avatarOption);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 绑定头像选择器和个人设置弹窗事件。
|
|
*
|
|
* @returns {void}
|
|
*/
|
|
export function bindProfileControls() {
|
|
if (profileControlEventsBound || typeof document === "undefined") {
|
|
return;
|
|
}
|
|
|
|
profileControlEventsBound = true;
|
|
document.addEventListener("click", (event) => {
|
|
if (!(event.target instanceof Element)) {
|
|
return;
|
|
}
|
|
|
|
// 头像选择器包含静态按钮和动态头像项,统一用 data-* 事件代理承接。
|
|
if (event.target.closest("[data-avatar-picker-close]")) {
|
|
event.preventDefault();
|
|
callGlobal("closeAvatarPicker");
|
|
return;
|
|
}
|
|
|
|
if (handleAvatarOptionClick(event.target)) {
|
|
event.preventDefault();
|
|
return;
|
|
}
|
|
|
|
if (event.target.closest("[data-avatar-save]")) {
|
|
event.preventDefault();
|
|
callGlobal("saveAvatar");
|
|
return;
|
|
}
|
|
|
|
if (event.target.closest("[data-avatar-upload-trigger]")) {
|
|
event.preventDefault();
|
|
// 上传按钮只负责打开隐藏的 file input,上传校验仍由存量 handleAvatarUpload 负责。
|
|
document.getElementById("avatar-upload-input")?.click();
|
|
return;
|
|
}
|
|
|
|
if (event.target.closest("[data-settings-modal-close]")) {
|
|
event.preventDefault();
|
|
callGlobal("closeSettingsModal");
|
|
return;
|
|
}
|
|
|
|
// 设置弹窗的保存、验证码、微信绑定仍走原请求函数,避免迁移中改变接口行为。
|
|
if (event.target.closest("[data-settings-save-password]")) {
|
|
event.preventDefault();
|
|
callGlobal("savePassword");
|
|
return;
|
|
}
|
|
|
|
if (event.target.closest("[data-settings-send-email-code]")) {
|
|
event.preventDefault();
|
|
callGlobal("sendEmailCode");
|
|
return;
|
|
}
|
|
|
|
if (event.target.closest("[data-settings-copy-wechat-code]")) {
|
|
event.preventDefault();
|
|
callGlobal("copyWechatBindCode");
|
|
return;
|
|
}
|
|
|
|
if (event.target.closest("[data-settings-generate-wechat-code]")) {
|
|
event.preventDefault();
|
|
callGlobal("generateWechatBindCode");
|
|
return;
|
|
}
|
|
|
|
if (event.target.closest("[data-settings-unbind-wechat]")) {
|
|
event.preventDefault();
|
|
callGlobal("unbindWechat");
|
|
return;
|
|
}
|
|
|
|
if (event.target.closest("[data-settings-save-profile]")) {
|
|
event.preventDefault();
|
|
callGlobal("saveSettings");
|
|
return;
|
|
}
|
|
|
|
if (event.target.closest("[data-settings-modal-panel]")) {
|
|
event.stopPropagation();
|
|
return;
|
|
}
|
|
|
|
// 只在点击设置弹窗遮罩时关闭,避免内容区点击被误判。
|
|
if (event.target.closest("[data-settings-modal-overlay]")) {
|
|
callGlobal("closeSettingsModal");
|
|
}
|
|
});
|
|
|
|
document.addEventListener("change", (event) => {
|
|
if (!(event.target instanceof HTMLInputElement) || !event.target.matches("[data-avatar-upload-input]")) {
|
|
return;
|
|
}
|
|
|
|
// 保留原上传函数的文件大小校验、接口请求和在线名单刷新逻辑。
|
|
callGlobal("handleAvatarUpload", event.target);
|
|
});
|
|
}
|