Add files via upload

This commit is contained in:
Cola-Echo
2025-12-23 15:20:30 +08:00
committed by GitHub
parent 1fe6d34355
commit 3824a441f6
6 changed files with 75 additions and 464 deletions

View File

@@ -677,10 +677,6 @@ function handleFuncItemClick(func) {
showTransferPage();
}
return;
case 'time':
hideFuncPanel();
showTimePicker();
return;
case 'listen':
hideFuncPanel();
// 群聊不支持一起听
@@ -758,194 +754,5 @@ export function initFuncPanel() {
// 初始化音乐面板事件
initMusicEvents();
initMusicShareListener();
initTimePickerEvents();
initListenTogether();
}
// ============ 时间选择器相关 ============
// 存储选择的时间null 表示使用当前时间)
let selectedTime = null;
let timePickerInited = false;
// 时间选择器当前选中的值
let pickerValues = {
year: new Date().getFullYear(),
month: new Date().getMonth() + 1,
day: new Date().getDate(),
hour: new Date().getHours(),
minute: new Date().getMinutes(),
second: new Date().getSeconds()
};
// 获取选择的时间(供 chat.js 使用)
export function getSelectedTime() {
return selectedTime;
}
// 清除选择的时间
export function clearSelectedTime() {
selectedTime = null;
updateTimeIndicator();
}
// 显示时间选择器
function showTimePicker() {
const picker = document.getElementById('wechat-time-picker');
if (!picker) return;
// 初始化为当前时间
const now = new Date();
pickerValues = {
year: now.getFullYear(),
month: now.getMonth() + 1,
day: now.getDate(),
hour: now.getHours(),
minute: now.getMinutes(),
second: now.getSeconds()
};
renderTimePickerColumns();
updateTimePickerDisplay();
picker.classList.remove('hidden');
}
// 隐藏时间选择器
function hideTimePicker() {
const picker = document.getElementById('wechat-time-picker');
picker?.classList.add('hidden');
}
// 渲染时间选择器列
function renderTimePickerColumns() {
const currentYear = new Date().getFullYear();
// 年份前后5年
renderPickerColumn('year', currentYear - 5, currentYear + 5, pickerValues.year, '年');
// 月份1-12
renderPickerColumn('month', 1, 12, pickerValues.month, '月');
// 日期:根据年月动态计算
const daysInMonth = new Date(pickerValues.year, pickerValues.month, 0).getDate();
renderPickerColumn('day', 1, daysInMonth, pickerValues.day, '日');
// 小时0-23
renderPickerColumn('hour', 0, 23, pickerValues.hour, '时');
// 分钟0-59
renderPickerColumn('minute', 0, 59, pickerValues.minute, '分');
// 秒0-59
renderPickerColumn('second', 0, 59, pickerValues.second, '秒');
}
// 渲染单个列
function renderPickerColumn(type, min, max, selected, suffix) {
const container = document.getElementById(`wechat-time-picker-${type}`);
if (!container) return;
let html = '';
for (let i = min; i <= max; i++) {
const value = type === 'year' ? i : i.toString().padStart(2, '0');
const isSelected = i === selected;
html += `<div class="wechat-time-picker-item${isSelected ? ' selected' : ''}" data-value="${i}">${value}${suffix}</div>`;
}
container.innerHTML = html;
// 滚动到选中项
setTimeout(() => {
const selectedItem = container.querySelector('.selected');
if (selectedItem) {
container.scrollTop = selectedItem.offsetTop - container.offsetHeight / 2 + selectedItem.offsetHeight / 2;
}
}, 0);
}
// 更新显示的时间
function updateTimePickerDisplay() {
const display = document.getElementById('wechat-time-picker-display');
if (!display) return;
const { year, month, day, hour, minute, second } = pickerValues;
display.textContent = `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')} ${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}:${second.toString().padStart(2, '0')}`;
}
// 更新输入框旁的时间指示器
function updateTimeIndicator() {
let indicator = document.getElementById('wechat-time-indicator');
if (!selectedTime) {
indicator?.remove();
return;
}
if (!indicator) {
const inputArea = document.querySelector('.wechat-chat-input-area');
if (!inputArea) return;
indicator = document.createElement('div');
indicator.id = 'wechat-time-indicator';
indicator.className = 'wechat-time-indicator';
inputArea.insertBefore(indicator, inputArea.firstChild);
}
const date = new Date(selectedTime);
const month = date.getMonth() + 1;
const day = date.getDate();
const hour = date.getHours().toString().padStart(2, '0');
const minute = date.getMinutes().toString().padStart(2, '0');
indicator.innerHTML = `
<span class="wechat-time-indicator-text">${month}${day}${hour}:${minute}</span>
<button class="wechat-time-indicator-clear" id="wechat-time-indicator-clear">✕</button>
`;
// 绑定清除按钮
document.getElementById('wechat-time-indicator-clear')?.addEventListener('click', (e) => {
e.stopPropagation();
clearSelectedTime();
});
}
// 初始化时间选择器事件
function initTimePickerEvents() {
if (timePickerInited) return;
timePickerInited = true;
// 监听列项点击
document.addEventListener('click', (e) => {
const item = e.target.closest('.wechat-time-picker-item');
if (!item) return;
const column = item.closest('.wechat-time-picker-column');
if (!column) return;
const type = column.dataset.type;
const value = parseInt(item.dataset.value);
// 更新选中值
pickerValues[type] = value;
// 更新选中样式
column.querySelectorAll('.wechat-time-picker-item').forEach(el => {
el.classList.toggle('selected', parseInt(el.dataset.value) === value);
});
// 如果改变了年或月,需要重新渲染日期列
if (type === 'year' || type === 'month') {
const daysInMonth = new Date(pickerValues.year, pickerValues.month, 0).getDate();
if (pickerValues.day > daysInMonth) {
pickerValues.day = daysInMonth;
}
renderPickerColumn('day', 1, daysInMonth, pickerValues.day, '日');
}
updateTimePickerDisplay();
});
// 确认按钮
document.getElementById('wechat-time-picker-confirm')?.addEventListener('click', () => {
const { year, month, day, hour, minute, second } = pickerValues;
selectedTime = new Date(year, month - 1, day, hour, minute, second).getTime();
hideTimePicker();
updateTimeIndicator();
showToast('已设置发送时间', '⏰');
});
}

40
chat.js
View File

@@ -17,7 +17,6 @@ import { startVoiceCall } from './voice-call.js';
import { startVideoCall } from './video-call.js';
import { showOpenRedPacket, generateRedPacketId } from './red-packet.js';
import { showReceiveTransferPage, generateTransferId } from './transfer.js';
import { getSelectedTime, clearSelectedTime } from './chat-func-panel.js';
// 当前聊天的联系人索引
export let currentChatIndex = -1;
@@ -1393,6 +1392,7 @@ export async function sendMessage(messageText, isMultipleMessages = false, isVoi
const now = new Date();
const timeStr = `${now.getFullYear()}-${(now.getMonth()+1).toString().padStart(2,'0')}-${now.getDate().toString().padStart(2,'0')} ${now.getHours().toString().padStart(2,'0')}:${now.getMinutes().toString().padStart(2,'0')}`;
const msgTimestamp = Date.now();
let messagesToSend = [];
if (isMultipleMessages && Array.isArray(messageText)) {
@@ -1413,8 +1413,6 @@ export async function sendMessage(messageText, isMultipleMessages = false, isVoi
// 清除引用
clearQuote();
const msgTimestamp = Date.now();
for (let i = 0; i < messagesToSend.length; i++) {
const msg = messagesToSend[i];
// 只有第一条消息带引用
@@ -1453,15 +1451,6 @@ export async function sendMessage(messageText, isMultipleMessages = false, isVoi
? `[用户发送了语音消息,内容是:${messagesToSend.join('\n')}]`
: messagesToSend.join('\n');
// 如果有选择的时间,添加时间上下文
const selectedTime = getSelectedTime();
if (selectedTime) {
const timeDate = new Date(selectedTime);
const timeStr = `${timeDate.getFullYear()}${timeDate.getMonth() + 1}${timeDate.getDate()}${timeDate.getHours().toString().padStart(2, '0')}:${timeDate.getMinutes().toString().padStart(2, '0')}`;
combinedMessage = `[当前时间:${timeStr}]\n${combinedMessage}`;
clearSelectedTime();
}
// 如果有引用,添加引用上下文
if (quote) {
let quoteDesc;
@@ -1981,15 +1970,6 @@ export async function sendStickerMessage(stickerUrl, description = '') {
? `[用户发送了一个表情包:${description}]`
: '[用户发送了一个表情包]';
// 如果有选择的时间,添加时间上下文
const selectedTime = getSelectedTime();
if (selectedTime) {
const timeDate = new Date(selectedTime);
const timeStr = `${timeDate.getFullYear()}${timeDate.getMonth() + 1}${timeDate.getDate()}${timeDate.getHours().toString().padStart(2, '0')}:${timeDate.getMinutes().toString().padStart(2, '0')}`;
aiPrompt = `[当前时间:${timeStr}]\n${aiPrompt}`;
clearSelectedTime();
}
const aiResponse = await callAI(contact, aiPrompt);
// 只有用户还在当前聊天时才隐藏打字指示器
@@ -2371,15 +2351,6 @@ export async function sendPhotoMessage(description) {
const { callAI } = await import('./ai.js');
let aiPrompt = `[用户发送了一张照片,图片描述:${polishedDescription}]`;
// 如果有选择的时间,添加时间上下文
const selectedTime = getSelectedTime();
if (selectedTime) {
const timeDate = new Date(selectedTime);
const timeStr = `${timeDate.getFullYear()}${timeDate.getMonth() + 1}${timeDate.getDate()}${timeDate.getHours().toString().padStart(2, '0')}:${timeDate.getMinutes().toString().padStart(2, '0')}`;
aiPrompt = `[当前时间:${timeStr}]\n${aiPrompt}`;
clearSelectedTime();
}
const aiResponse = await callAI(contact, aiPrompt);
// 只有用户还在当前聊天时才隐藏打字指示器
@@ -2861,15 +2832,6 @@ export async function sendBatchMessages(messages) {
const { callAI } = await import('./ai.js');
let combinedPrompt = promptParts.join('\n');
// 如果有选择的时间,添加时间上下文
const selectedTime = getSelectedTime();
if (selectedTime) {
const timeDate = new Date(selectedTime);
const timeStr = `${timeDate.getFullYear()}${timeDate.getMonth() + 1}${timeDate.getDate()}${timeDate.getHours().toString().padStart(2, '0')}:${timeDate.getMinutes().toString().padStart(2, '0')}`;
combinedPrompt = `[当前时间:${timeStr}]\n${combinedPrompt}`;
clearSelectedTime();
}
const aiResponse = await callAI(contact, combinedPrompt);
// 只有用户还在当前聊天时才隐藏打字指示器

View File

@@ -10,6 +10,7 @@ import { escapeHtml, sleep, formatMessageTime, calculateVoiceDuration, bindImage
import { getUserAvatarHTML, refreshChatList, getUserPersonaFromST } from './ui.js';
import { getSTChatContext, HAKIMI_HEADER } from './ai.js';
import { playMusic as kugouPlayMusic } from './music.js';
import { showMessageMenu } from './message-menu.js';
// 当前群聊的索引
export let currentGroupChatIndex = -1;
@@ -813,25 +814,29 @@ function renderGroupChatHistory(groupChat, members, chatHistory) {
// 生成群聊静态语音气泡
function generateGroupVoiceBubbleStatic(content, isSelf) {
const seconds = calculateVoiceDuration(content);
const width = Math.min(50 + seconds * 3, 180);
const safeContent = (content || '').toString();
const seconds = calculateVoiceDuration(safeContent);
const width = Math.min(60 + seconds * 4, 200);
const voiceId = 'voice_' + Math.random().toString(36).substring(2, 9);
// 用户消息波形朝右,角色消息波形朝左
const wavesSvg = isSelf
? `<svg viewBox="0 0 24 24" width="20" height="20"><path d="M3 12h2v4H3zM7 8h2v8H7zm4 4h2v6h-2zm4-6h2v10h-2z" fill="currentColor"/></svg>`
: `<svg viewBox="0 0 24 24" width="20" height="20"><path d="M19 12h2v4h-2zm-4-4h2v8h-2zm-4 4h2v6h-2zm-4-6h2v10H7z" fill="currentColor"/></svg>`;
// 用户消息:波形在左,秒数在右
// 角色消息:秒数在左,波形在右
// WiFi信号样式的三条弧线图标与单聊保持一致
const wavesSvg = `<svg class="wechat-voice-waves-icon" viewBox="0 0 24 24" width="18" height="18">
<circle class="wechat-voice-arc arc1" cx="5" cy="12" r="2" fill="currentColor"/>
<path class="wechat-voice-arc arc2" d="M10 8 A 5 5 0 0 1 10 16" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round"/>
<path class="wechat-voice-arc arc3" d="M15 4 A 10 10 0 0 1 15 20" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round"/>
</svg>`;
// 用户消息:时长在左,波形在右
// 角色消息:波形在左,时长在右
const bubbleInner = isSelf
? `<span class="wechat-voice-waves">${wavesSvg}</span><span class="wechat-voice-duration">${seconds}</span>`
: `<span class="wechat-voice-duration">${seconds}</span><span class="wechat-voice-waves">${wavesSvg}</span>`;
? `<span class="wechat-voice-duration">${seconds}"</span><span class="wechat-voice-waves">${wavesSvg}</span>`
: `<span class="wechat-voice-waves">${wavesSvg}</span><span class="wechat-voice-duration">${seconds}"</span>`;
return `
<div class="wechat-voice-bubble ${isSelf ? 'self' : ''}" style="width: ${width}px" data-voice-id="${voiceId}">
<div class="wechat-voice-bubble ${isSelf ? 'self' : ''}" style="width: ${width}px" data-voice-id="${voiceId}" data-voice-content="${escapeHtml(safeContent)}">
${bubbleInner}
</div>
<div class="wechat-voice-text hidden" id="${voiceId}">${escapeHtml(content)}</div>
<div class="wechat-voice-text hidden" id="${voiceId}">${escapeHtml(safeContent)}</div>
`;
}
@@ -866,17 +871,43 @@ function generateGroupMusicCardStatic(musicInfo) {
`;
}
// 绑定群聊语音气泡点击事件
// 绑定群聊语音气泡点击事件(播放动画 + 显示上方菜单,与单聊保持一致)
function bindGroupVoiceBubbleEvents(container) {
const voiceBubbles = container.querySelectorAll('.wechat-voice-bubble:not([data-bound])');
voiceBubbles.forEach(bubble => {
bubble.setAttribute('data-bound', 'true');
bubble.addEventListener('click', () => {
const voiceId = bubble.dataset.voiceId;
const textEl = document.getElementById(voiceId);
if (textEl) {
textEl.classList.toggle('hidden');
// 获取父消息元素
const messageEl = bubble.closest('.wechat-message');
// 计算消息索引
const allMessages = Array.from(container.querySelectorAll('.wechat-message'));
const msgIndex = allMessages.indexOf(messageEl);
// 点击事件:播放动画 + 显示上方菜单
bubble.addEventListener('click', (e) => {
e.stopPropagation();
// 切换播放状态
const isPlaying = bubble.classList.contains('playing');
if (isPlaying) {
bubble.classList.remove('playing');
} else {
// 停止其他正在播放的语音
document.querySelectorAll('.wechat-voice-bubble.playing').forEach(b => {
b.classList.remove('playing');
});
bubble.classList.add('playing');
// 模拟播放时间后停止
const duration = parseInt(bubble.querySelector('.wechat-voice-duration')?.textContent) || 3;
setTimeout(() => {
bubble.classList.remove('playing');
}, duration * 1000);
}
// 显示上方菜单
showMessageMenu(bubble, msgIndex, e);
});
});
}

View File

@@ -1634,8 +1634,8 @@ function init() {
}
if (typeof jQuery === 'function') {
jQuery(() => init());
jQuery(() => setTimeout(init, 500));
} else {
document.addEventListener('DOMContentLoaded', init, { once: true });
document.addEventListener('DOMContentLoaded', () => setTimeout(init, 500), { once: true });
}

View File

@@ -205,28 +205,6 @@ export function generatePhoneHTML() {
<input type="file" id="wechat-chat-bg-file" accept="image/*" style="display: none;">
</div>
</div>
<!-- 图片裁剪弹窗 -->
<div id="wechat-cropper-modal" class="wechat-modal hidden">
<div class="wechat-modal-content wechat-modal-cropper" style="position: relative; max-width: 350px; max-height: 90vh; overflow: hidden;">
<button class="wechat-modal-close-x" id="wechat-cropper-cancel">×</button>
<div class="wechat-modal-title">裁剪图片</div>
<div class="wechat-cropper-container" id="wechat-cropper-container">
<canvas id="wechat-cropper-canvas"></canvas>
<div class="wechat-cropper-overlay" id="wechat-cropper-overlay">
<div class="wechat-cropper-box" id="wechat-cropper-box">
<div class="wechat-cropper-handle nw"></div>
<div class="wechat-cropper-handle ne"></div>
<div class="wechat-cropper-handle sw"></div>
<div class="wechat-cropper-handle se"></div>
</div>
</div>
</div>
<div class="wechat-cropper-hint" style="font-size: 11px; color: var(--wechat-text-secondary); text-align: center; margin: 8px 0;">拖动选择区域,拖动角落调整大小</div>
<div class="wechat-modal-actions">
<button class="wechat-btn wechat-btn-primary" id="wechat-cropper-confirm">确认裁剪</button>
</div>
</div>
</div>
<div class="wechat-chat">
<div class="wechat-chat-messages" id="wechat-chat-messages"></div>
</div>
@@ -248,7 +226,6 @@ export function generatePhoneHTML() {
<div class="wechat-func-page" data-page="1">
<div class="wechat-func-grid">
<div class="wechat-func-item" data-func="voice"><div class="wechat-func-icon"><svg viewBox="0 0 24 24"><path d="M12 1a4 4 0 00-4 4v7a4 4 0 008 0V5a4 4 0 00-4-4z" stroke="currentColor" stroke-width="1.5" fill="none"/><path d="M19 10v2a7 7 0 01-14 0v-2M12 19v4M8 23h8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none"/></svg></div><span>语音输入</span></div>
<div class="wechat-func-item" data-func="time"><div class="wechat-func-icon"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="1.5" fill="none"/><path d="M12 6v6l4 2" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg></div><span>时间</span></div>
<div class="wechat-func-item" data-func="listen"><div class="wechat-func-icon"><svg viewBox="0 0 24 24"><path d="M3 18v-6a9 9 0 0118 0v6" stroke="currentColor" stroke-width="1.5" fill="none"/><path d="M21 19a2 2 0 01-2 2h-1a2 2 0 01-2-2v-3a2 2 0 012-2h3v5z" stroke="currentColor" stroke-width="1.5" fill="none"/><path d="M3 19a2 2 0 002 2h1a2 2 0 002-2v-3a2 2 0 00-2-2H3v5z" stroke="currentColor" stroke-width="1.5" fill="none"/></svg></div><span>一起听</span></div>
<div class="wechat-func-item" data-func="music"><div class="wechat-func-icon"><svg viewBox="0 0 24 24"><path d="M9 18V5l12-2v13" stroke="currentColor" stroke-width="1.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/><circle cx="6" cy="18" r="3" stroke="currentColor" stroke-width="1.5" fill="none"/><circle cx="18" cy="16" r="3" stroke="currentColor" stroke-width="1.5" fill="none"/></svg></div><span>音乐</span></div>
</div>
@@ -270,36 +247,6 @@ export function generatePhoneHTML() {
<button class="wechat-btn wechat-expand-send" id="wechat-expand-send">发送</button>
</div>
</div>
<!-- 时间选择器面板 -->
<div class="wechat-time-picker hidden" id="wechat-time-picker">
<div class="wechat-time-picker-header">
<span class="wechat-time-picker-title">发送时间</span>
</div>
<div class="wechat-time-picker-display" id="wechat-time-picker-display">2025-12-22 21:33:19</div>
<div class="wechat-time-picker-columns">
<div class="wechat-time-picker-column" data-type="year">
<div class="wechat-time-picker-items" id="wechat-time-picker-year"></div>
</div>
<div class="wechat-time-picker-column" data-type="month">
<div class="wechat-time-picker-items" id="wechat-time-picker-month"></div>
</div>
<div class="wechat-time-picker-column" data-type="day">
<div class="wechat-time-picker-items" id="wechat-time-picker-day"></div>
</div>
<div class="wechat-time-picker-column" data-type="hour">
<div class="wechat-time-picker-items" id="wechat-time-picker-hour"></div>
</div>
<div class="wechat-time-picker-column" data-type="minute">
<div class="wechat-time-picker-items" id="wechat-time-picker-minute"></div>
</div>
<div class="wechat-time-picker-column" data-type="second">
<div class="wechat-time-picker-items" id="wechat-time-picker-second"></div>
</div>
</div>
<div class="wechat-time-picker-footer">
<button class="wechat-time-picker-confirm" id="wechat-time-picker-confirm">完成</button>
</div>
</div>
<!-- 表情面板 -->
<div class="wechat-emoji-panel hidden" id="wechat-emoji-panel">
<div class="wechat-emoji-tabs">
@@ -342,6 +289,29 @@ export function generatePhoneHTML() {
${generateTransferPageHTML()}
${generateReceiveTransferPageHTML()}
${generateTransferRefundConfirmHTML()}
<!-- 图片裁剪弹窗(全局) -->
<div id="wechat-cropper-modal" class="wechat-modal hidden">
<div class="wechat-modal-content wechat-modal-cropper" style="position: relative; max-width: 350px; max-height: 90vh; overflow: hidden;">
<button class="wechat-modal-close-x" id="wechat-cropper-cancel">×</button>
<div class="wechat-modal-title">裁剪图片</div>
<div class="wechat-cropper-container" id="wechat-cropper-container">
<canvas id="wechat-cropper-canvas"></canvas>
<div class="wechat-cropper-overlay" id="wechat-cropper-overlay">
<div class="wechat-cropper-box" id="wechat-cropper-box">
<div class="wechat-cropper-handle nw"></div>
<div class="wechat-cropper-handle ne"></div>
<div class="wechat-cropper-handle sw"></div>
<div class="wechat-cropper-handle se"></div>
</div>
</div>
</div>
<div class="wechat-cropper-hint" style="font-size: 11px; color: var(--wechat-text-secondary); text-align: center; margin: 8px 0;">拖动选择区域,拖动角落调整大小</div>
<div class="wechat-modal-actions">
<button class="wechat-btn wechat-btn-primary" id="wechat-cropper-confirm">确认裁剪</button>
</div>
</div>
</div>
</div>
<!-- 隐藏的文件输入 -->

159
style.css
View File

@@ -8767,165 +8767,6 @@
color: rgba(255,255,255,0.7);
}
/* ===== 时间选择器 ===== */
.wechat-time-picker {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: var(--wechat-white);
border-top: 1px solid var(--wechat-border);
z-index: 100;
animation: slideUp 0.25s ease;
}
@keyframes slideUp {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
}
}
.wechat-time-picker.hidden {
display: none;
}
.wechat-time-picker-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
border-bottom: 1px solid var(--wechat-border);
}
.wechat-time-picker-title {
font-size: 15px;
font-weight: 600;
color: var(--wechat-text);
}
.wechat-time-picker-confirm {
background: var(--wechat-green);
color: white;
border: none;
border-radius: 6px;
padding: 6px 16px;
font-size: 14px;
cursor: pointer;
transition: opacity 0.2s;
}
.wechat-time-picker-confirm:active {
opacity: 0.8;
}
.wechat-time-picker-display {
text-align: center;
padding: 10px;
font-size: 14px;
color: var(--wechat-green);
font-weight: 500;
background: var(--wechat-bg);
}
.wechat-time-picker-columns {
display: flex;
height: 180px;
overflow: hidden;
}
.wechat-time-picker-column {
flex: 1;
height: 100%;
overflow-y: auto;
scroll-snap-type: y mandatory;
-webkit-overflow-scrolling: touch;
}
/* 隐藏滚动条 */
.wechat-time-picker-column::-webkit-scrollbar {
display: none;
}
.wechat-time-picker-column {
scrollbar-width: none;
-ms-overflow-style: none;
}
.wechat-time-picker-item {
height: 36px;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
color: var(--wechat-text-secondary);
cursor: pointer;
scroll-snap-align: center;
transition: all 0.15s;
}
.wechat-time-picker-item:active {
background: var(--wechat-bg);
}
.wechat-time-picker-item.selected {
color: var(--wechat-text);
font-weight: 600;
font-size: 16px;
}
/* 时间指示器(输入框上方) */
.wechat-time-indicator {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 6px 12px;
background: rgba(7, 193, 96, 0.1);
border-bottom: 1px solid var(--wechat-border);
}
.wechat-time-indicator-text {
font-size: 12px;
color: var(--wechat-green);
font-weight: 500;
}
.wechat-time-indicator-clear {
width: 18px;
height: 18px;
border: none;
background: var(--wechat-text-secondary);
color: white;
border-radius: 50%;
font-size: 10px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
opacity: 0.6;
transition: opacity 0.2s;
}
.wechat-time-indicator-clear:hover {
opacity: 1;
}
/* 暗色模式时间选择器 */
.wechat-dark .wechat-time-picker {
background: var(--wechat-white);
}
.wechat-dark .wechat-time-picker-display {
background: var(--wechat-bg);
}
.wechat-dark .wechat-time-indicator {
background: rgba(62, 181, 117, 0.15);
}
/* ========== 一起听功能样式 ========== */
/* 搜索页面 */