Добавлена возможность добавлять свою музыку и аудиокниги через YouTube ссылки

This commit is contained in:
Madina 2026-08-10 09:25:27 +00:00
parent 875d3d6518
commit 7859dfed10

View File

@ -396,6 +396,68 @@
to { height: 20px; }
}
.equalizer.off span { animation: none; height: 5px; }
/* Моя музыка */
.my-music {
margin-top: 20px;
background: rgba(255,255,255,0.1);
border-radius: 12px;
padding: 20px;
}
.my-music h4 { margin: 0 0 15px; font-size: 16px; }
.add-music-form {
display: flex;
gap: 10px;
margin-bottom: 15px;
flex-wrap: wrap;
}
.add-music-form input {
flex: 1;
min-width: 200px;
padding: 12px;
border-radius: 8px;
border: none;
font-size: 14px;
}
.add-music-form button {
padding: 12px 24px;
background: white;
color: #667eea;
border: none;
border-radius: 8px;
cursor: pointer;
font-weight: bold;
}
.my-playlist {
max-height: 300px;
overflow-y: auto;
}
.playlist-item {
display: flex;
align-items: center;
gap: 10px;
padding: 10px;
background: rgba(255,255,255,0.1);
border-radius: 8px;
margin: 8px 0;
cursor: pointer;
transition: 0.2s;
}
.playlist-item:hover { background: rgba(255,255,255,0.2); }
.playlist-item.active { background: rgba(255,255,255,0.3); }
.playlist-item .remove {
margin-left: auto;
opacity: 0.7;
cursor: pointer;
font-size: 18px;
}
.playlist-item .remove:hover { opacity: 1; }
.music-type {
font-size: 12px;
padding: 3px 8px;
border-radius: 4px;
background: rgba(255,255,255,0.2);
}
</style>
</head>
<body>
@ -441,6 +503,22 @@
<span>🔊</span>
</div>
<div class="now-playing" id="now-playing">Выберите плейлист и нажмите ▶</div>
<!-- Моя музыка -->
<div class="my-music">
<h4>🎵 Моя музыка</h4>
<div class="add-music-form">
<input type="text" id="music-url" placeholder="YouTube ссылка (https://youtube.com/watch?v=...)">
<input type="text" id="music-name" placeholder="Название песни/аудиокниги">
<select id="music-type" style="padding:12px; border-radius:8px; border:none;">
<option value="song">Песня</option>
<option value="audiobook">Аудиокнига</option>
<option value="motivation">Мотивация</option>
</select>
<button onclick="addMyMusic()">+ Добавить</button>
</div>
<div class="my-playlist" id="my-playlist"></div>
</div>
</div>
<div class="goal-info">
@ -671,6 +749,9 @@
]
};
// Моя музыка (загружается из localStorage)
let myMusic = JSON.parse(localStorage.getItem('myMusic') || '[]');
let currentPlaylist = 'workout';
let currentTrackIndex = 0;
let isPlaying = false;
@ -717,6 +798,105 @@
loadTrack(currentTrackIndex);
}
// === МОЯ МУЗЫКА ===
function addMyMusic() {
const url = document.getElementById('music-url').value.trim();
const name = document.getElementById('music-name').value.trim() || 'Мой трек';
const type = document.getElementById('music-type').value;
if (!url) {
alert('Вставь ссылку на YouTube');
return;
}
// Конвертация YouTube ссылки в embed
let embedUrl = url;
const videoId = extractVideoId(url);
if (videoId) {
embedUrl = 'https://www.youtube.com/embed/' + videoId + '?autoplay=1&loop=1&playlist=' + videoId;
}
myMusic.push({
id: Date.now(),
name: name,
url: embedUrl,
type: type,
videoId: videoId
});
localStorage.setItem('myMusic', JSON.stringify(myMusic));
renderMyPlaylist();
document.getElementById('music-url').value = '';
document.getElementById('music-name').value = '';
}
function extractVideoId(url) {
const match = url.match(/(?:v=|\/)([a-zA-Z0-9_-]{11})/);
return match ? match[1] : null;
}
function renderMyPlaylist() {
const container = document.getElementById('my-playlist');
if (!container) return;
if (myMusic.length === 0) {
container.innerHTML = '<p style="opacity:0.7; font-size:14px;">Пока нет добавленных треков. Добавь любимую музыку!</p>';
return;
}
container.innerHTML = myMusic.map(track => {
const typeLabels = { song: '🎵', audiobook: '📚', motivation: '🔥' };
const isActive = currentPlaylist === 'my' && currentTrackIndex === myMusic.findIndex(t => t.id === track.id);
return '<div class="playlist-item' + (isActive ? ' active' : '') + '" onclick="playMyTrack(' + track.id + ')">' +
'<span style="font-size:20px;">' + typeLabels[track.type] + '</span>' +
'<span style="flex:1; font-size:14px;">' + track.name + '</span>' +
'<span class="music-type">' + (track.type === 'song' ? 'Песня' : track.type === 'audiobook' ? 'Аудиокнига' : 'Мотивация') + '</span>' +
'<span class="remove" onclick="event.stopPropagation(); removeMyTrack(' + track.id + ')">×</span>' +
'</div>';
}).join('');
}
function playMyTrack(id) {
const index = myMusic.findIndex(t => t.id === id);
if (index === -1) return;
currentPlaylist = 'my';
currentTrackIndex = index;
loadTrack(index, true);
}
function removeMyTrack(id) {
myMusic = myMusic.filter(t => t.id !== id);
localStorage.setItem('myMusic', JSON.stringify(myMusic));
renderMyPlaylist();
}
function loadTrack(index, isMyMusic = false) {
let playlist;
if (isMyMusic || currentPlaylist === 'my') {
playlist = myMusic;
if (isMyMusic) currentPlaylist = 'my';
} else {
playlist = playlists[currentPlaylist];
}
if (!playlist || playlist.length === 0) return;
const track = playlist[index];
document.getElementById('now-playing').textContent = '🎵 ' + track.name;
if (player && player.loadVideoById) {
const videoId = track.videoId || track.url.split('v=')[1].split('&')[0];
player.loadVideoById(videoId);
player.setVolume(70);
}
updatePlayButton();
if (currentPlaylist === 'my') renderMyPlaylist();
}
function loadTrack(index) {
const playlist = playlists[currentPlaylist];
if (!playlist || playlist.length === 0) return;
@ -1360,19 +1540,10 @@
// Инициализация плеера при загрузке
setTimeout(() => initPlayer(), 1000);
init();
// Загрузка моей музыки
renderMyPlaylist();
// Сброс воды каждый день
setInterval(() => {
const lastWaterDate = localStorage.getItem('lastWaterDate');
const todayStr = new Date().toDateString();
if (lastWaterDate !== todayStr) {
progressData.waterToday = 0;
localStorage.setItem('lastWaterDate', todayStr);
localStorage.setItem('madinaProgress', JSON.stringify(progressData));
renderNutrition();
}
}, 60000); // Проверка каждую минуту
init();
</script>
<!-- Скрытый iframe для музыкального плеера -->