221 lines
6.3 KiB
JavaScript
221 lines
6.3 KiB
JavaScript
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
|
|
};
|
|
}
|