import { createLogger } from '../../shared/logger.js'; const logger = createLogger('profile'); const DEFAULT_AVATAR = '/images/p1.png'; const MAX_AVATAR_SIZE = 2 * 1024 * 1024; const USER_ID_PREFIX = 'user_'; const USER_ID_LENGTH = 8; const USER_ID_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; function getElement(id) { return document.getElementById(id); } function setAvatarPreview(avatarUrl) { const userAvatar = getElement('userAvatar'); const avatarPreview = getElement('avatarPreview'); if (userAvatar) { userAvatar.src = avatarUrl; } if (avatarPreview) { avatarPreview.src = avatarUrl; } } function updateUserName(name) { const userName = getElement('userName'); if (userName) { userName.textContent = name; } } function generateUserId() { let result = USER_ID_PREFIX; for (let i = 0; i < USER_ID_LENGTH; i++) { result += USER_ID_CHARS.charAt(Math.floor(Math.random() * USER_ID_CHARS.length)); } return result; } function readStoredSettings() { const rawSettings = localStorage.getItem('userSettings'); if (!rawSettings) { return null; } return JSON.parse(rawSettings); } function getCurrentSettingsPayload() { const nicknameInput = getElement('nicknameInput'); const userIdInput = getElement('userIdInput'); const avatarPreview = getElement('avatarPreview'); return { userId: userIdInput ? userIdInput.value : generateUserId(), name: nicknameInput ? (nicknameInput.value || '\u6211') : '\u6211', avatar: avatarPreview ? (avatarPreview.src || DEFAULT_AVATAR) : DEFAULT_AVATAR }; } async function uploadAvatar(formData) { const response = await fetch('/api/upload/avatar', { method: 'POST', body: formData }); if (!response.ok) { throw new Error('\u4e0a\u4f20\u5931\u8d25'); } return response.json(); } export function createProfileSettingsController({ store, notify }) { let documentEventsBound = false; function loadUserSettings() { try { const settings = readStoredSettings(); if (!settings) { const nextUserId = generateUserId(); const userIdInput = getElement('userIdInput'); if (userIdInput) { userIdInput.value = nextUserId; } setAvatarPreview(DEFAULT_AVATAR); saveSettings(); return; } const userIdInput = getElement('userIdInput'); const nicknameInput = getElement('nicknameInput'); if (settings.userId && userIdInput) { userIdInput.value = settings.userId; } if (settings.name && nicknameInput) { nicknameInput.value = settings.name; } updateUserName(settings.name || '\u6211'); setAvatarPreview(settings.avatar || DEFAULT_AVATAR); } catch (error) { logger.error('Error loading user settings:', error); setAvatarPreview(DEFAULT_AVATAR); } } function saveSettings() { const settings = getCurrentSettingsPayload(); localStorage.setItem('userSettings', JSON.stringify(settings)); store.syncSocketUserInfo(settings); updateUserName(settings.name); setAvatarPreview(settings.avatar); notify('\u8bbe\u7f6e\u5df2\u4fdd\u5b58', 'success'); } async function handleAvatarUpload(event) { const file = event.target.files[0]; if (!file) { return; } if (!file.type.startsWith('image/')) { notify('\u8bf7\u9009\u62e9\u56fe\u7247\u6587\u4ef6', 'error'); return; } if (file.size > MAX_AVATAR_SIZE) { notify('\u56fe\u7247\u5927\u5c0f\u4e0d\u80fd\u8d85\u8fc72MB', 'error'); return; } const formData = new FormData(); formData.append('avatar', file); const userIdInput = getElement('userIdInput'); if (userIdInput) { formData.append('userId', userIdInput.value); } notify('\u6b63\u5728\u4e0a\u4f20\u5934\u50cf...'); try { const data = await uploadAvatar(formData); if (!data.success || !data.avatarUrl) { throw new Error(data.message || '\u672a\u77e5\u9519\u8bef'); } setAvatarPreview(data.avatarUrl); saveSettings(); notify('\u5934\u50cf\u4e0a\u4f20\u6210\u529f', 'success'); } catch (error) { logger.error('Error uploading avatar:', error); setAvatarPreview(DEFAULT_AVATAR); notify('\u5934\u50cf\u4e0a\u4f20\u5931\u8d25\uff0c\u8bf7\u91cd\u8bd5', 'error'); } } function copyUserId() { const userIdInput = getElement('userIdInput'); if (!userIdInput) { return; } userIdInput.select(); document.execCommand('copy'); notify('\u7528\u6237ID\u5df2\u590d\u5236\u5230\u526a\u8d34\u677f', 'success'); } function toggleSettingsMenu() { const settingsMenu = getElement('settingsMenu'); if (settingsMenu) { settingsMenu.classList.toggle('hidden'); } } function bindDocumentEvents() { if (documentEventsBound) { return; } document.addEventListener('click', (event) => { const settingsMenu = getElement('settingsMenu'); const userSettingsButton = getElement('userSettingsBtn'); if ( settingsMenu && userSettingsButton && !settingsMenu.contains(event.target) && !userSettingsButton.contains(event.target) ) { settingsMenu.classList.add('hidden'); } }); documentEventsBound = true; } function bindWindowHandlers() { window.saveSettings = saveSettings; window.handleAvatarUpload = handleAvatarUpload; window.copyUserId = copyUserId; window.toggleSettingsMenu = toggleSettingsMenu; } return { bindDocumentEvents, bindWindowHandlers, copyUserId, handleAvatarUpload, loadUserSettings, saveSettings, toggleSettingsMenu }; }