mirror of
https://github.com/Cola-Echo/Cola.git
synced 2026-06-05 23:25:51 +00:00
Add files via upload
This commit is contained in:
@@ -42,6 +42,8 @@ let listenState = {
|
||||
audioElement: null,
|
||||
progressInterval: null,
|
||||
pauseTimeout: null, // 暂停后自动播放下一首的计时器
|
||||
playMode: 'normal', // 播放模式: 'normal' | 'loop' | 'shuffle'
|
||||
songsSinceAIChange: 0, // AI换歌保底计数器
|
||||
};
|
||||
|
||||
// 导出图标供其他模块使用
|
||||
@@ -227,6 +229,8 @@ export async function startListenTogether(song, contactIndex = currentChatIndex)
|
||||
audioElement: null,
|
||||
progressInterval: null,
|
||||
pauseTimeout: null,
|
||||
playMode: 'normal',
|
||||
songsSinceAIChange: 0,
|
||||
};
|
||||
|
||||
// 隐藏搜索页,显示等待页面
|
||||
@@ -317,9 +321,112 @@ async function onSongEnded() {
|
||||
listenState.isPlaying = false;
|
||||
updatePlayButton();
|
||||
|
||||
// 20%几率AI换歌
|
||||
if (Math.random() < 0.2) {
|
||||
// 计数器+1
|
||||
listenState.songsSinceAIChange++;
|
||||
|
||||
// 20%几率AI换歌,或保底5首必换(所有模式下都有效)
|
||||
if (Math.random() < 0.2 || listenState.songsSinceAIChange >= 5) {
|
||||
listenState.songsSinceAIChange = 0; // 重置计数器
|
||||
await aiSelectSong();
|
||||
return;
|
||||
}
|
||||
|
||||
// 根据播放模式处理
|
||||
if (listenState.playMode === 'loop') {
|
||||
// 单曲循环:重新播放当前歌曲
|
||||
await playListenSong();
|
||||
} else if (listenState.playMode === 'shuffle') {
|
||||
// 随机播放:播放随机歌曲
|
||||
await playRandomSong();
|
||||
}
|
||||
// 正常模式不做处理,等待用户操作
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换单曲循环模式
|
||||
*/
|
||||
function toggleLoopMode() {
|
||||
const loopBtn = document.getElementById('wechat-listen-loop-btn');
|
||||
const shuffleBtn = document.getElementById('wechat-listen-shuffle-btn');
|
||||
|
||||
if (listenState.playMode === 'loop') {
|
||||
// 取消单曲循环
|
||||
listenState.playMode = 'normal';
|
||||
loopBtn?.classList.remove('active');
|
||||
showToast('已关闭单曲循环');
|
||||
} else {
|
||||
// 开启单曲循环
|
||||
listenState.playMode = 'loop';
|
||||
loopBtn?.classList.add('active');
|
||||
shuffleBtn?.classList.remove('active');
|
||||
showToast('单曲循环');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换随机播放模式
|
||||
*/
|
||||
function toggleShuffleMode() {
|
||||
const loopBtn = document.getElementById('wechat-listen-loop-btn');
|
||||
const shuffleBtn = document.getElementById('wechat-listen-shuffle-btn');
|
||||
|
||||
if (listenState.playMode === 'shuffle') {
|
||||
// 取消随机播放
|
||||
listenState.playMode = 'normal';
|
||||
shuffleBtn?.classList.remove('active');
|
||||
showToast('已关闭随机播放');
|
||||
} else {
|
||||
// 开启随机播放
|
||||
listenState.playMode = 'shuffle';
|
||||
shuffleBtn?.classList.add('active');
|
||||
loopBtn?.classList.remove('active');
|
||||
showToast('随机播放');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机播放歌曲
|
||||
*/
|
||||
async function playRandomSong() {
|
||||
try {
|
||||
// 随机关键词列表
|
||||
const keywords = [
|
||||
'热门', '流行', '经典', '抖音', '网红',
|
||||
'伤感', '甜蜜', '治愈', '怀旧', '浪漫',
|
||||
'周杰伦', '林俊杰', '邓紫棋', '薛之谦', '陈奕迅',
|
||||
'Taylor Swift', 'Ed Sheeran', 'Bruno Mars',
|
||||
'说唱', '民谣', '摇滚', '电子', 'R&B'
|
||||
];
|
||||
const randomKeyword = keywords[Math.floor(Math.random() * keywords.length)];
|
||||
|
||||
// 搜索歌曲
|
||||
const results = await searchMusic(randomKeyword);
|
||||
if (results && results.length > 0) {
|
||||
// 随机选择一首
|
||||
const randomIndex = Math.floor(Math.random() * Math.min(results.length, 10));
|
||||
const newSong = results[randomIndex];
|
||||
|
||||
listenState.currentSong = newSong;
|
||||
|
||||
// 更新界面
|
||||
const coverEl = document.getElementById('wechat-listen-cover');
|
||||
const nameEl = document.getElementById('wechat-listen-song-name');
|
||||
const artistEl = document.getElementById('wechat-listen-song-artist');
|
||||
|
||||
if (coverEl && newSong.cover) coverEl.src = newSong.cover;
|
||||
if (nameEl) nameEl.textContent = newSong.name || '未知歌曲';
|
||||
if (artistEl) artistEl.textContent = newSong.artist || '未知歌手';
|
||||
|
||||
// 播放
|
||||
await playMusic(newSong.id, newSong.platform, newSong.name, newSong.artist);
|
||||
listenState.isPlaying = true;
|
||||
updatePlayButton();
|
||||
|
||||
// AI对新歌的反应
|
||||
await triggerAIAutoNextReaction(newSong);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[可乐] 随机播放失败:', e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,19 +611,45 @@ function filterListenMessage(text) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理AI回复 - 纯文字消息
|
||||
* 处理AI回复 - 纯文字消息,按换行分条发送
|
||||
*/
|
||||
async function processAIResponse(aiResponse) {
|
||||
if (!aiResponse) return;
|
||||
|
||||
const parts = splitAIMessages(aiResponse);
|
||||
// 先用 ||| 分割,再按换行分割
|
||||
let parts = splitAIMessages(aiResponse);
|
||||
|
||||
// 对每个部分再按换行分割
|
||||
const allParts = [];
|
||||
for (const part of parts) {
|
||||
// 按换行符分割成多条消息
|
||||
const lines = part.split(/\n+/).map(l => l.trim()).filter(l => l);
|
||||
allParts.push(...lines);
|
||||
}
|
||||
|
||||
for (const part of allParts) {
|
||||
if (!listenState.isConnected) break;
|
||||
|
||||
let reply = filterListenMessage(part);
|
||||
if (!reply) continue;
|
||||
|
||||
// 检查是否包含换歌标签
|
||||
const changeSongMatch = reply.match(/\[换歌[::]\s*(.+?)\]/);
|
||||
if (changeSongMatch) {
|
||||
const songKeyword = changeSongMatch[1].trim();
|
||||
// 显示AI的说明文字(去掉换歌标签)
|
||||
const displayText = reply.replace(/\[换歌[::][^\]]*\]/g, '').trim();
|
||||
if (displayText) {
|
||||
showListenTypingIndicator();
|
||||
await sleep(400 + Math.random() * 600);
|
||||
hideListenTypingIndicator();
|
||||
addListenMessage('ai', displayText);
|
||||
}
|
||||
// 搜索并播放新歌
|
||||
await changeSongByKeyword(songKeyword, true);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 直接发送纯文字消息
|
||||
showListenTypingIndicator();
|
||||
await sleep(400 + Math.random() * 600);
|
||||
@@ -885,11 +1018,14 @@ function bindListenEvents() {
|
||||
// 播放/暂停
|
||||
document.getElementById('wechat-listen-play-btn')?.addEventListener('click', handlePlayPauseClick);
|
||||
|
||||
// 星星按钮 - 打开颜色选择器
|
||||
document.getElementById('wechat-listen-color-btn')?.addEventListener('click', toggleColorPicker);
|
||||
// 搜索按钮 - 打开换歌面板
|
||||
document.getElementById('wechat-listen-search-btn')?.addEventListener('click', showChangeSongPanel);
|
||||
|
||||
// 颜色选择器选项点击
|
||||
document.getElementById('wechat-listen-color-picker')?.addEventListener('click', handleColorOptionClick);
|
||||
// 单曲循环按钮
|
||||
document.getElementById('wechat-listen-loop-btn')?.addEventListener('click', toggleLoopMode);
|
||||
|
||||
// 随机播放按钮
|
||||
document.getElementById('wechat-listen-shuffle-btn')?.addEventListener('click', toggleShuffleMode);
|
||||
|
||||
// 结束按钮
|
||||
document.getElementById('wechat-listen-end-btn')?.addEventListener('click', exitListenTogether);
|
||||
@@ -1115,6 +1251,8 @@ function cancelListenTogether() {
|
||||
audioElement: null,
|
||||
progressInterval: null,
|
||||
pauseTimeout: null,
|
||||
playMode: 'normal',
|
||||
songsSinceAIChange: 0,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1165,6 +1303,8 @@ export async function exitListenTogether() {
|
||||
audioElement: null,
|
||||
progressInterval: null,
|
||||
pauseTimeout: null,
|
||||
playMode: 'normal',
|
||||
songsSinceAIChange: 0,
|
||||
};
|
||||
|
||||
// AI 结束一起听后的回复
|
||||
|
||||
@@ -973,8 +973,6 @@ export async function generateNewMomentForContact(contactIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
showToast('正在生成朋友圈...', '⏳');
|
||||
|
||||
try {
|
||||
// 调用 AI 生成朋友圈内容
|
||||
const momentContent = await generateMomentContent(contact);
|
||||
|
||||
@@ -1530,12 +1530,18 @@ function generateListenTogetherHTML() {
|
||||
|
||||
<!-- 控制按钮(底部) -->
|
||||
<div class="wechat-listen-controls">
|
||||
<button class="wechat-listen-ctrl-btn" id="wechat-listen-star-btn" title="更换背景">
|
||||
<svg viewBox="0 0 24 24" width="20" height="20"><polygon points="12,2 15.09,8.26 22,9.27 17,14.14 18.18,21.02 12,17.77 5.82,21.02 7,14.14 2,9.27 8.91,8.26" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<button class="wechat-listen-ctrl-btn" id="wechat-listen-search-btn" title="搜索换歌">
|
||||
<svg viewBox="0 0 24 24" width="20" height="20"><circle cx="11" cy="11" r="8" stroke="currentColor" stroke-width="2" fill="none"/><path d="M21 21l-4.35-4.35" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
|
||||
</button>
|
||||
<button class="wechat-listen-ctrl-btn" id="wechat-listen-loop-btn" title="单曲循环">
|
||||
<svg viewBox="0 0 24 24" width="20" height="20"><path d="M17 2l4 4-4 4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/><path d="M3 11v-1a4 4 0 014-4h14" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/><path d="M7 22l-4-4 4-4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/><path d="M21 13v1a4 4 0 01-4 4H3" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/><text x="12" y="14" text-anchor="middle" font-size="8" fill="currentColor" font-weight="bold">1</text></svg>
|
||||
</button>
|
||||
<button class="wechat-listen-ctrl-btn wechat-listen-play-btn" id="wechat-listen-play-btn">
|
||||
<svg viewBox="0 0 24 24" width="24" height="24"><polygon points="5,3 19,12 5,21" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</button>
|
||||
<button class="wechat-listen-ctrl-btn" id="wechat-listen-shuffle-btn" title="随机播放">
|
||||
<svg viewBox="0 0 24 24" width="20" height="20"><path d="M16 3h5v5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/><path d="M4 20L21 3" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/><path d="M21 16v5h-5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/><path d="M15 15l6 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/><path d="M4 4l5 5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg>
|
||||
</button>
|
||||
<button class="wechat-listen-ctrl-btn" id="wechat-listen-end-btn" title="结束">
|
||||
<svg viewBox="0 0 24 24" width="20" height="20"><line x1="18" y1="6" x2="6" y2="18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><line x1="6" y1="6" x2="18" y2="18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
|
||||
</button>
|
||||
|
||||
15
style.css
15
style.css
@@ -9468,6 +9468,15 @@
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.wechat-listen-ctrl-btn.active {
|
||||
color: #07c160;
|
||||
background: rgba(7, 193, 96, 0.15);
|
||||
}
|
||||
|
||||
.wechat-listen-ctrl-btn.active:hover {
|
||||
background: rgba(7, 193, 96, 0.25);
|
||||
}
|
||||
|
||||
.wechat-listen-play-btn {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
padding: 14px;
|
||||
@@ -9559,17 +9568,17 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 16px;
|
||||
padding: 8px 16px;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.wechat-listen-input-text {
|
||||
flex: 1;
|
||||
padding: 10px 14px;
|
||||
padding: 8px 14px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border: none;
|
||||
border-radius: 20px;
|
||||
border-radius: 18px;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
outline: none;
|
||||
|
||||
Reference in New Issue
Block a user