210 lines
9.6 KiB
PHP
210 lines
9.6 KiB
PHP
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png">
|
||
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png">
|
||
<link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png">
|
||
<title>Pets at Home</title>
|
||
<meta name="description" content="Create a personalized love song for your pet with our fun and easy tool.">
|
||
<link rel="stylesheet" href="assets/css/style.css">
|
||
|
||
<?php include('opengraph.php'); ?>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
|
||
<?php include('header.php'); ?>
|
||
|
||
<div class="body-container">
|
||
|
||
<img class="jukebox-banner-mb" src="assets/images/jukebox-banner-mb.png" alt="Jukebox" />
|
||
<img class="jukebox-banner-dt" src="assets/images/jukebox-banner-dt.png" alt="Jukebox" />
|
||
|
||
<div class="title">Your Pet Love Song <br/>is on its way.</div>
|
||
<div class="sub-title">Won’t take a minute...</div>
|
||
|
||
<div class="melody-record-container">
|
||
<img class="melody-record" src="./assets/images/blank-record.png"
|
||
alt="Melody Record" />
|
||
<svg class="record-text-overlay" viewBox="0 0 100 100">
|
||
<path id="arc-top" d="M 38,50 A 12,12 0 0,1 62,50" fill="transparent" />
|
||
<path id="arc-bottom" d="M 62,50 A 12,12 0 0,1 38,50" fill="transparent" />
|
||
<text class="top-text">
|
||
<textPath href="#arc-top" startOffset="50%" text-anchor="middle">Unleashed</textPath>
|
||
</text>
|
||
<text class="bottom-text">
|
||
<textPath href="#arc-bottom" startOffset="50%" text-anchor="middle">Melody</textPath>
|
||
</text>
|
||
</svg>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<?php include('footer.php'); ?>
|
||
|
||
</div>
|
||
|
||
<script>
|
||
(function() {
|
||
// Get session_id from URL query parameter
|
||
const urlParams = new URLSearchParams(window.location.search);
|
||
let sessionId = urlParams.get('session_id');
|
||
|
||
if (!sessionId) {
|
||
// No session_id in URL, check localStorage
|
||
try {
|
||
const submissionData = localStorage.getItem('submission_data');
|
||
|
||
if (submissionData) {
|
||
const data = JSON.parse(submissionData);
|
||
|
||
if (data.entries && data.entries.length > 0) {
|
||
// Sort entries by timestamp (newest first) and get the latest
|
||
const sortedEntries = data.entries.sort((a, b) => {
|
||
return new Date(b.timestamp) - new Date(a.timestamp);
|
||
});
|
||
|
||
const latestEntry = sortedEntries[0];
|
||
sessionId = latestEntry.session_id;
|
||
console.log(`Loading session from localStorage: ${sessionId} from ${latestEntry.timestamp}`);
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.error(`Error reading from localStorage: ${error}`);
|
||
}
|
||
|
||
// If still no session_id, redirect to home
|
||
if (!sessionId) {
|
||
window.location.href = '/';
|
||
return;
|
||
}
|
||
}
|
||
|
||
// Configuration
|
||
const API_BASE_URL = 'https://valentinesong.oliver.digital/back';
|
||
const POLL_INTERVAL = 10 * 1000; // 10 seconds
|
||
const MAX_POLL_TIME = 10 * 60 * 1000; // 10 minutes
|
||
|
||
// State
|
||
const startTime = Date.now();
|
||
let pollTimer = null;
|
||
|
||
async function pollStatus() {
|
||
// Check if we've exceeded max poll time
|
||
if (Date.now() - startTime > MAX_POLL_TIME) {
|
||
clearInterval(pollTimer);
|
||
showTimeoutError();
|
||
return;
|
||
}
|
||
|
||
try {
|
||
const response = await fetch(`${API_BASE_URL}/api/submissions/${sessionId}/status`);
|
||
|
||
if (!response.ok) {
|
||
if (response.status === 404) {
|
||
// Session not found, redirect to home
|
||
window.location.href = '/';
|
||
console.log(`polling - no session found in API -> ${sessionId}`)
|
||
return;
|
||
}
|
||
console.error(`Status check failed: ${response.status}`);
|
||
return;
|
||
}
|
||
|
||
const data = await response.json();
|
||
|
||
if (data.status === 'success') {
|
||
// Generation complete, redirect to result page
|
||
clearInterval(pollTimer);
|
||
window.location.href = `result.php?session_id=${sessionId}`;
|
||
} else if (data.status === 'fail') {
|
||
// Generation failed, redirect to result page (shows failure message)
|
||
clearInterval(pollTimer);
|
||
window.location.href = `result.php?session_id=${sessionId}`;
|
||
}
|
||
// For 'pending' or 'processing', continue polling
|
||
} catch (error) {
|
||
console.error(`Error polling status: ${error}`);
|
||
// Continue polling on network errors
|
||
}
|
||
}
|
||
|
||
function showTimeoutError() {
|
||
// Find and REMOVE the record container
|
||
const recordContainer = document.querySelector('.melody-record-container');
|
||
if (recordContainer) {
|
||
recordContainer.remove();
|
||
}
|
||
|
||
// Select the existing title elements
|
||
const bodyTitle = document.querySelector('.body-container div.title');
|
||
const bodySubTitle = document.querySelector('.body-container div.sub-title');
|
||
|
||
// Update the text
|
||
if (bodyTitle) {
|
||
bodyTitle.textContent = 'Taking longer than expected...';
|
||
}
|
||
if (bodySubTitle) {
|
||
bodySubTitle.textContent = 'Your song is still being created. Please check back in a few minutes.';
|
||
}
|
||
|
||
// Create the NEW buttons div
|
||
const newDiv = document.createElement('div');
|
||
newDiv.className = 'action-btns';
|
||
newDiv.innerHTML = `
|
||
<button class="make-another-song-btn" onclick="window.location.reload()">
|
||
Check Again
|
||
</button>
|
||
<button class="make-another-song-btn" onclick="window.location.href='/'">
|
||
Create New Song
|
||
</button>
|
||
`;
|
||
|
||
// Place buttons after the sub-title
|
||
if (bodySubTitle) {
|
||
bodySubTitle.after(newDiv);
|
||
} else if (bodyTitle) {
|
||
bodyTitle.after(newDiv);
|
||
}
|
||
}
|
||
|
||
// Start polling immediately and then every 10 seconds
|
||
pollStatus();
|
||
pollTimer = setInterval(pollStatus, POLL_INTERVAL);
|
||
})();
|
||
|
||
(function() {
|
||
const phrases = [
|
||
{ top: "Unleashed", bottom: "Melody" },
|
||
{ top: "Paws &", bottom: "Play" },
|
||
{ top: "Tail-Wagging", bottom: "Tunes" },
|
||
{ top: "Furry", bottom: "Forever" }
|
||
];
|
||
let index = 0;
|
||
let textSwitchInterval = 10; // Seconds between switches
|
||
let intervalMs = textSwitchInterval * 1000;
|
||
let fadeMs = intervalMs * 0.06; // Relative fade timing (e.g., 600ms for 10s)
|
||
|
||
const overlay = document.querySelector('.record-text-overlay');
|
||
const topText = document.querySelector('.top-text textPath');
|
||
const bottomText = document.querySelector('.bottom-text textPath');
|
||
|
||
if (overlay && topText && bottomText) {
|
||
overlay.style.transition = `opacity ${fadeMs}ms ease-in-out`;
|
||
|
||
setInterval(() => {
|
||
overlay.classList.add('text-hidden');
|
||
setTimeout(() => {
|
||
index = (index + 1) % phrases.length;
|
||
topText.textContent = phrases[index].top;
|
||
bottomText.textContent = phrases[index].bottom;
|
||
overlay.classList.remove('text-hidden');
|
||
}, fadeMs + 100); // Wait for fade out before swap
|
||
}, intervalMs);
|
||
}
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|