头像设置
This commit is contained in:
@@ -9,6 +9,45 @@
|
|||||||
<link rel="stylesheet" href="../css/style.css">
|
<link rel="stylesheet" href="../css/style.css">
|
||||||
</head>
|
</head>
|
||||||
<body class="h-screen w-screen flex flex-col text-white bg-grid relative">
|
<body class="h-screen w-screen flex flex-col text-white bg-grid relative">
|
||||||
|
<!-- 用户设置区域 -->
|
||||||
|
<div class="absolute top-4 right-4 z-10">
|
||||||
|
<button id="userSettingsBtn" class="flex items-center gap-2 glass px-3 py-2 rounded-full hover:bg-white/10 transition-colors">
|
||||||
|
<img id="userAvatar" src="/images/p1.png" class="w-8 h-8 rounded-full object-cover">
|
||||||
|
<span id="userName" class="text-sm font-medium">我</span>
|
||||||
|
<i class="fas fa-chevron-down text-xs text-gray-400"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- 设置菜单 -->
|
||||||
|
<div id="settingsMenu" class="hidden absolute top-full right-0 mt-2 glass rounded-xl shadow-lg w-48 z-20">
|
||||||
|
<div class="p-4 border-b border-white/10">
|
||||||
|
<h3 class="text-sm font-medium mb-2">个人设置</h3>
|
||||||
|
<div class="space-y-3">
|
||||||
|
<div>
|
||||||
|
<label class="block text-xs text-gray-400 mb-1">昵称</label>
|
||||||
|
<input type="text" id="nicknameInput" class="w-full bg-transparent border border-white/20 rounded-lg px-3 py-2 text-sm text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="输入昵称">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-xs text-gray-400 mb-1">头像</label>
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<img id="avatarPreview" src="/images/p1.png" class="w-10 h-10 rounded-full object-cover">
|
||||||
|
<input type="file" id="avatarInput" accept="image/*" class="hidden" onchange="handleAvatarUpload(event)">
|
||||||
|
<button onclick="document.getElementById('avatarInput').click()" class="text-xs text-indigo-400 hover:text-indigo-300 transition-colors">更换头像</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-xs text-gray-400 mb-1">用户ID</label>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<input type="text" id="userIdInput" class="flex-1 bg-transparent border border-white/20 rounded-lg px-3 py-2 text-sm text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500" readonly>
|
||||||
|
<button onclick="copyUserId()" class="text-xs text-indigo-400 hover:text-indigo-300 transition-colors">复制</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="p-2">
|
||||||
|
<button onclick="saveSettings()" class="w-full px-4 py-2 text-sm text-white bg-indigo-600 hover:bg-indigo-700 rounded-lg transition-colors">保存设置</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<!--
|
<!--
|
||||||
============================================================
|
============================================================
|
||||||
初始连接界面
|
初始连接界面
|
||||||
|
|||||||
@@ -166,9 +166,134 @@ function bindEvents() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 生成8位的用户ID
|
||||||
|
function generateUserId() {
|
||||||
|
// 生成8位随机字符串,包含字母和数字
|
||||||
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
|
let result = 'user_';
|
||||||
|
for (let i = 0; i < 8; i++) {
|
||||||
|
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载用户设置
|
||||||
|
function loadUserSettings() {
|
||||||
|
const userSettings = localStorage.getItem('userSettings');
|
||||||
|
if (userSettings) {
|
||||||
|
try {
|
||||||
|
const settings = JSON.parse(userSettings);
|
||||||
|
|
||||||
|
// 设置用户ID
|
||||||
|
if (settings.userId) {
|
||||||
|
document.getElementById('userIdInput').value = settings.userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置昵称
|
||||||
|
if (settings.name) {
|
||||||
|
document.getElementById('nicknameInput').value = settings.name;
|
||||||
|
document.getElementById('userName').textContent = settings.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置头像
|
||||||
|
if (settings.avatar) {
|
||||||
|
document.getElementById('userAvatar').src = settings.avatar;
|
||||||
|
document.getElementById('avatarPreview').src = settings.avatar;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error loading user settings:', error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 生成新的用户ID
|
||||||
|
const newUserId = generateUserId();
|
||||||
|
document.getElementById('userIdInput').value = newUserId;
|
||||||
|
|
||||||
|
// 保存默认设置
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存用户设置
|
||||||
|
function saveSettings() {
|
||||||
|
const settings = {
|
||||||
|
userId: document.getElementById('userIdInput').value,
|
||||||
|
name: document.getElementById('nicknameInput').value || '我',
|
||||||
|
avatar: document.getElementById('avatarPreview').src
|
||||||
|
};
|
||||||
|
|
||||||
|
localStorage.setItem('userSettings', JSON.stringify(settings));
|
||||||
|
|
||||||
|
// 更新界面显示
|
||||||
|
document.getElementById('userName').textContent = settings.name;
|
||||||
|
document.getElementById('userAvatar').src = settings.avatar;
|
||||||
|
|
||||||
|
showNotification('设置已保存', 'success');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理头像上传
|
||||||
|
function handleAvatarUpload(event) {
|
||||||
|
const file = event.target.files[0];
|
||||||
|
if (file) {
|
||||||
|
// 检查文件类型
|
||||||
|
if (!file.type.startsWith('image/')) {
|
||||||
|
showNotification('请选择图片文件', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查文件大小
|
||||||
|
if (file.size > 2 * 1024 * 1024) { // 2MB限制
|
||||||
|
showNotification('图片大小不能超过2MB', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取图片文件
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = function(e) {
|
||||||
|
const imageUrl = e.target.result;
|
||||||
|
document.getElementById('avatarPreview').src = imageUrl;
|
||||||
|
showNotification('头像已更新', 'success');
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 复制用户ID到剪贴板
|
||||||
|
function copyUserId() {
|
||||||
|
const userIdInput = document.getElementById('userIdInput');
|
||||||
|
userIdInput.select();
|
||||||
|
document.execCommand('copy');
|
||||||
|
showNotification('用户ID已复制到剪贴板', 'success');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换设置菜单
|
||||||
|
function toggleSettingsMenu() {
|
||||||
|
const settingsMenu = document.getElementById('settingsMenu');
|
||||||
|
settingsMenu.classList.toggle('hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击外部关闭设置菜单
|
||||||
|
document.addEventListener('click', function(event) {
|
||||||
|
const settingsMenu = document.getElementById('settingsMenu');
|
||||||
|
const userSettingsBtn = document.getElementById('userSettingsBtn');
|
||||||
|
|
||||||
|
if (!settingsMenu.contains(event.target) && !userSettingsBtn.contains(event.target)) {
|
||||||
|
settingsMenu.classList.add('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 绑定用户设置相关事件
|
||||||
|
function bindUserSettingsEvents() {
|
||||||
|
// 设置按钮点击事件
|
||||||
|
const userSettingsBtn = document.getElementById('userSettingsBtn');
|
||||||
|
if (userSettingsBtn) {
|
||||||
|
userSettingsBtn.addEventListener('click', toggleSettingsMenu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 页面加载完成后初始化
|
// 页面加载完成后初始化
|
||||||
window.addEventListener('DOMContentLoaded', () => {
|
window.addEventListener('DOMContentLoaded', () => {
|
||||||
bindEvents();
|
bindEvents();
|
||||||
|
bindUserSettingsEvents();
|
||||||
|
|
||||||
// 检查本地存储中是否有连接ID
|
// 检查本地存储中是否有连接ID
|
||||||
const savedConnectionId = localStorage.getItem('connectionId');
|
const savedConnectionId = localStorage.getItem('connectionId');
|
||||||
@@ -178,6 +303,9 @@ window.addEventListener('DOMContentLoaded', () => {
|
|||||||
connectionIdInput.value = savedConnectionId;
|
connectionIdInput.value = savedConnectionId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 加载用户设置
|
||||||
|
loadUserSettings();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 导出全局函数
|
// 导出全局函数
|
||||||
@@ -185,4 +313,7 @@ window.showNotification = showNotification;
|
|||||||
window.joinCall = joinCall;
|
window.joinCall = joinCall;
|
||||||
window.createCall = createCall;
|
window.createCall = createCall;
|
||||||
window.selectConnectionId = selectConnectionId;
|
window.selectConnectionId = selectConnectionId;
|
||||||
window.selectConnectionId = selectConnectionId;
|
window.saveSettings = saveSettings;
|
||||||
|
window.handleAvatarUpload = handleAvatarUpload;
|
||||||
|
window.copyUserId = copyUserId;
|
||||||
|
window.toggleSettingsMenu = toggleSettingsMenu;
|
||||||
|
|||||||
@@ -49,9 +49,36 @@ class CallStateManager {
|
|||||||
async init() {
|
async init() {
|
||||||
// 初始化配置
|
// 初始化配置
|
||||||
await this.setupConfig();
|
await this.setupConfig();
|
||||||
|
// 加载用户设置
|
||||||
|
this.loadUserSettings();
|
||||||
// 获取本地摄像头视频流
|
// 获取本地摄像头视频流
|
||||||
await this.getLocalStream();
|
await this.getLocalStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 加载用户设置
|
||||||
|
loadUserSettings() {
|
||||||
|
const userSettings = localStorage.getItem('userSettings');
|
||||||
|
if (userSettings) {
|
||||||
|
try {
|
||||||
|
const settings = JSON.parse(userSettings);
|
||||||
|
|
||||||
|
// 更新本地用户信息
|
||||||
|
if (settings.name || settings.avatar) {
|
||||||
|
this.state.session.localUser = {
|
||||||
|
...this.state.session.localUser,
|
||||||
|
id: settings.userId || this.state.session.localUser.id,
|
||||||
|
name: settings.name || this.state.session.localUser.name,
|
||||||
|
avatar: settings.avatar || this.state.session.localUser.avatar
|
||||||
|
};
|
||||||
|
|
||||||
|
// 通知UI更新
|
||||||
|
this.notify({ type: 'USER_SETTINGS_UPDATED', user: this.state.session.localUser });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error loading user settings:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
async setupConfig() {
|
async setupConfig() {
|
||||||
const res = await getServerConfig();
|
const res = await getServerConfig();
|
||||||
this.useWebSocket = res.useWebSocket;
|
this.useWebSocket = res.useWebSocket;
|
||||||
|
|||||||
Reference in New Issue
Block a user