From dd837101089c838c3705da29325c190d430609d1 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Thu, 13 Nov 2025 12:53:49 +0000 Subject: [PATCH] Auto commit: 2025-11-13T12:53:49.811Z --- api/mood.php | 56 +++++++++++++++++++++++++++++++++++++++++++++++ assets/js/main.js | 35 ++++++++++++++++++++++++----- index.php | 8 +++++++ 3 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 api/mood.php diff --git a/api/mood.php b/api/mood.php new file mode 100644 index 0000000..59489fd --- /dev/null +++ b/api/mood.php @@ -0,0 +1,56 @@ + 'User not logged in']); + exit; +} + +$moodText = isset($_POST['mood_text']) ? trim($_POST['mood_text']) : ''; + +if (empty($moodText)) { + echo json_encode(['error' => 'Mood text cannot be empty']); + exit; +} + +$musicDatabase = [ + 'happy' => [['videoId' => 'y6Sxv-sUYtM', 'title' => 'Pharrell Williams - Happy'], ['videoId' => 'HgzGwKwLmgM', 'title' => 'Queen - Don\'t Stop Me Now'], ['videoId' => 'iPUmE-tne5s', 'title' => 'Katrina & The Waves - Walking On Sunshine']], + 'sad' => [['videoId' => 'hLQl3WQQoQ0', 'title' => 'Adele - Someone Like You'], ['videoId' => '8AHCfZTRGiI', 'title' => 'Johnny Cash - Hurt'], ['videoId' => 'XFkzRNyygfk', 'title' => 'Radiohead - Creep']], + 'energetic' => [['videoId' => 'v2AC41dglnM', 'title' => 'AC/DC - Thunderstruck'], ['videoId' => 'o1tj2zJ2Wvg', 'title' => 'Guns N\' Roses - Welcome to the Jungle'], ['videoId' => 'CD-E-LDc384', 'title' => 'Metallica - Enter Sandman']], + 'calm' => [['videoId' => 'vNwYtllyt3Q', 'title' => 'Brian Eno - Music for Airports 1/1'], ['videoId' => 'S-Xm7s9eGxU', 'title' => 'Erik Satie - Gymnopédie No. 1'], ['videoId' => 'U3u4pQ44e14', 'title' => 'Claude Debussy - Clair de Lune']], + 'upbeat' => [['videoId' => 'FGBhQbmPwH8', 'title' => 'Daft Punk - One More Time'], ['videoId' => 'sy1dYFGkPUE', 'title' => 'Justice - D.A.N.C.E.'], ['videoId' => 'Cj8JrQ9w5jY', 'title' => 'LCD Soundsystem - Daft Punk Is Playing at My House']] +]; + +$prompt = 'Based on the following text, what is the primary mood? Please respond with only one of the following words: happy, sad, energetic, calm, upbeat. Text: ' . $moodText; + +$resp = LocalAIApi::createResponse([ + 'input' => [ + ['role' => 'system', 'content' => 'You are a mood detection assistant.'], + ['role' => 'user', 'content' => $prompt], + ], +]); + +if (!empty($resp['success'])) { + $decoded = LocalAIApi::decodeJsonFromResponse($resp); + $aiReply = $decoded['choices'][0]['message']['content'] ?? ''; + $mood = trim(strtolower($aiReply)); + + if (array_key_exists($mood, $musicDatabase)) { + $songs = $musicDatabase[$mood]; + echo json_encode(['mood' => $mood, 'songs' => $songs]); + } else { + // Fallback to a random mood if the AI response is not a valid key + $randomMood = array_rand($musicDatabase); + $songs = $musicDatabase[$randomMood]; + echo json_encode(['mood' => $randomMood, 'songs' => $songs]); + } +} else { + // Fallback to a random mood if the AI call fails + $randomMood = array_rand($musicDatabase); + $songs = $musicDatabase[$randomMood]; + echo json_encode(['mood' => $randomMood, 'songs' => $songs]); +} diff --git a/assets/js/main.js b/assets/js/main.js index 0fe114d..c87c7b5 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -1,5 +1,7 @@ document.addEventListener('DOMContentLoaded', function () { const moodButtons = document.querySelectorAll('.btn-mood'); + const suggestByTextButton = document.getElementById('suggest-by-text'); + const moodTextInput = document.getElementById('mood-text'); const resultsSection = document.getElementById('results'); const resultsTitle = document.getElementById('results-title'); const videoGrid = document.getElementById('video-grid'); @@ -22,16 +24,37 @@ document.addEventListener('DOMContentLoaded', function () { moodButtons.forEach(btn => btn.classList.remove('active')); this.classList.add('active'); - displayVideos(mood); + const videos = musicDatabase[mood] || []; + displayVideos(videos, `Here's your ${mood} playlist`); }); }); - function displayVideos(mood) { - const videos = musicDatabase[mood] || []; + suggestByTextButton.addEventListener('click', function() { + const moodText = moodTextInput.value.trim(); + if (moodText === '') return; + + const formData = new FormData(); + formData.append('mood_text', moodText); + + fetch('/api/mood.php', { + method: 'POST', + body: formData + }) + .then(response => response.json()) + .then(data => { + if (data.error) { + alert('Error: ' + data.error); + return; + } + displayVideos(data.songs, `Based on your mood, we suggest...`); + }); + }); + + function displayVideos(videos, title) { videoGrid.innerHTML = ''; // Clear previous results if (videos.length > 0) { - resultsTitle.textContent = `Here's your ${mood} playlist`; + resultsTitle.textContent = title; resultsSection.style.display = 'block'; videos.forEach(video => { @@ -42,7 +65,7 @@ document.addEventListener('DOMContentLoaded', function () { videoContainer.className = 'video-container'; const iframe = document.createElement('iframe'); - iframe.src = `https://www.youtube.com/embed/${video.id}`; + iframe.src = `https://www.youtube.com/embed/${video.videoId}`; iframe.title = 'YouTube video player'; iframe.frameBorder = '0'; iframe.allow = 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture'; @@ -54,7 +77,7 @@ document.addEventListener('DOMContentLoaded', function () { const saveButton = document.createElement('button'); saveButton.className = 'btn btn-sm btn-outline-light mt-2'; saveButton.textContent = 'Save to favorites'; - saveButton.addEventListener('click', () => saveToFavorites(video.id, video.title)); + saveButton.addEventListener('click', () => saveToFavorites(video.videoId, video.title)); videoContainer.appendChild(saveButton); } diff --git a/index.php b/index.php index 9c4691a..5b13914 100644 --- a/index.php +++ b/index.php @@ -54,6 +54,14 @@ + +
+

Or, tell me how you feel:

+
+ + +
+