feat: 聊天室手机端自适应

- 新增 mobile-drawer.blade.php:手机端浮动按钮 + 工具菜单抽屉 + 名单抽屉(独立维护)
- frame.blade.php:手机端代码改为 @include 引入
- chat.css:添加 @media (max-width: 640px) 响应式样式
  - 隐藏桌面端工具条和右侧名单面板
  - 浮动按钮样式(位于屏幕中间偏右)
  - 抽屉组件从顶部向下展开
  - 手机端隐藏房间介绍、输入栏动作/字色/字号/禁音/分屏控件
  - 现有 modal 弹窗 max-width 自适应修复
- scripts.blade.php:重构 renderUserList 提取 _renderUserListToContainer
  - 修复代码损坏残留,补回 setAction/scrollToBottom/autoScrollEl
This commit is contained in:
2026-03-17 17:49:14 +08:00
parent bb63cc12c3
commit 35a80279e6
4 changed files with 552 additions and 25 deletions
+58 -25
View File
@@ -119,8 +119,12 @@
}
// ── 动作选择 ──────────────────────────────────────
/**
* 设置发言动作并聚焦输入框
*
* @param {string} act 动作名称
*/
function setAction(act) {
document.getElementById('action').value = act;
switchTab('users');
@@ -136,6 +140,9 @@
}
// ── 滚动到底部 ───────────────────────────────────
/**
* 将公聊窗口滚动到最新消息(受 autoScroll 开关控制)
*/
function scrollToBottom() {
if (autoScroll) {
container.scrollTop = container.scrollHeight;
@@ -143,9 +150,16 @@
}
// ── 渲染在线人员列表(支持排序) ──────────────────
function renderUserList() {
userList.innerHTML = '';
toUserSelect.innerHTML = '<option value="大家">大家</option>';
/**
* 核心渲染函数:将在线用户渲染到指定容器(桌面端名单区和手机端抽屉共用)
*
* @param {HTMLElement} targetContainer 目标 DOM 容器
* @param {string} sortBy 排序方式:'default' | 'name' | 'level'
* @param {string} keyword 搜索关键词(小写)
*/
function _renderUserListToContainer(targetContainer, sortBy, keyword) {
if (!targetContainer) return;
targetContainer.innerHTML = '';
// 在列表顶部添加"大家"条目(原版风格)
let allDiv = document.createElement('div');
@@ -154,7 +168,7 @@
allDiv.onclick = () => {
toUserSelect.value = '大家';
};
userList.appendChild(allDiv);
targetContainer.appendChild(allDiv);
// ── AI 小助手(仅当全局开关开启时显示,与普通用户风格一致)──
if (window.chatContext.chatBotEnabled) {
@@ -168,19 +182,9 @@
toUserSelect.value = 'AI小班长';
document.getElementById('content').focus();
};
userList.appendChild(botDiv);
// 在发言对象下拉框中也添加 AI 小助手
let botOption = document.createElement('option');
botOption.value = 'AI小班长';
botOption.textContent = '🤖 AI小班长';
toUserSelect.appendChild(botOption);
targetContainer.appendChild(botDiv);
}
// 获取排序方式
const sortSelect = document.getElementById('user-sort-select');
const sortBy = sortSelect ? sortSelect.value : 'default';
// 构建用户数组并排序
let userArr = [];
for (let username in onlineUsers) {
@@ -196,21 +200,23 @@
userArr.sort((a, b) => (b.user_level || 0) - (a.user_level || 0));
}
let count = userArr.length;
userArr.forEach(user => {
const username = user.username;
// 搜索过滤
if (keyword && !username.toLowerCase().includes(keyword)) return;
let item = document.createElement('div');
item.className = 'user-item';
item.dataset.username = username;
const headface = (user.headface || '1.gif').toLowerCase();
const headImgSrc = headface.startsWith('storage/') ? '/' + headface : '/images/headface/' + headface;
const headImgSrc = headface.startsWith('storage/') ? '/' + headface : '/images/headface/' +
headface;
// 徽章优先级:职务图标 > 管理员 > VIP
let badges = '';
if (user.position_icon) {
// 有职务:显示职务图标,hover 显示职务名称
const posTitle = (user.position_name || '在职') + ' · ' + username;
badges +=
`<span style="font-size:13px; margin-left:2px;" title="${posTitle}">${user.position_icon}</span>`;
@@ -235,23 +241,48 @@
};
// 双击打开用户名片弹窗(全局统一入口)
item.ondblclick = () => openUserCard(username);
userList.appendChild(item);
targetContainer.appendChild(item);
});
}
function renderUserList() {
userList.innerHTML = '';
toUserSelect.innerHTML = '<option value="大家">大家</option>';
// 获取排序方式和搜索词
const sortSelect = document.getElementById('user-sort-select');
const sortBy = sortSelect ? sortSelect.value : 'default';
const searchInput = document.getElementById('user-search-input');
const keyword = searchInput ? searchInput.value.trim().toLowerCase() : '';
// 调用核心渲染(桌面端名单容器)
_renderUserListToContainer(userList, sortBy, keyword);
// 重新填充发言对象下拉框(不过滤关键词,始终显示全部用户)
toUserSelect.innerHTML = '<option value="大家">大家</option>';
if (window.chatContext.chatBotEnabled) {
let botOption = document.createElement('option');
botOption.value = 'AI小班长';
botOption.textContent = '🤖 AI小班长';
toUserSelect.appendChild(botOption);
}
for (let username in onlineUsers) {
if (username !== window.chatContext.username) {
let option = document.createElement('option');
option.value = username;
option.textContent = username;
toUserSelect.appendChild(option);
}
});
}
const count = Object.keys(onlineUsers).length;
onlineCount.innerText = count;
onlineCountBottom.innerText = count;
const footer = document.getElementById('online-count-footer');
if (footer) footer.innerText = count;
if (footer) { footer.innerText = count; }
// 如果有搜索关键词,重新过滤
filterUserList();
// 派发用户列表更新事件,供手机端抽屉同步
window.dispatchEvent(new Event('chatroom:users-updated'));
}
/**
@@ -275,6 +306,8 @@
/**
* 追加消息到聊天窗格(原版风格:非气泡模式,逐行显示)
*/