INTEGRATE: Session recordings into main media library
CHANGED: Session recording storage system - Modified saveRecordedSession() to use 'capturedVideos' localStorage key (matches photo pattern) - Updated all Quick Play gallery functions to use consistent 'capturedVideos' key - Aligned with existing media library architecture for consistency ADDED: Captured videos to main library video tab - Integrated captured session videos into index.html video library display - Added captured videos section with proper metadata (date, duration, type) - Videos appear alongside game videos (background, task, reward, punishment) - Updated total video count to include captured session recordings IMPLEMENTED: Full video management in main library - Added playCapturedVideo() function with fullscreen player overlay - Added downloadCapturedVideo() function with proper filename generation - Added deleteCapturedVideo() function with confirmation and library refresh - All functions include proper error handling and user feedback RESULT: Unified media library experience - Session recordings now appear in main media library alongside photos - Users can manage all captured media from single location in index.html - Consistent interface for viewing, downloading, and deleting recordings - Seamless integration with existing library architecture and styling
This commit is contained in:
parent
6381c292e0
commit
325a71bf75
121
index.html
121
index.html
|
|
@ -4104,8 +4104,9 @@
|
|||
const taskVideos = videoLibrary.task || [];
|
||||
const rewardVideos = videoLibrary.reward || [];
|
||||
const punishmentVideos = videoLibrary.punishment || [];
|
||||
const capturedVideos = JSON.parse(localStorage.getItem('capturedVideos') || '[]');
|
||||
|
||||
let totalVideos = backgroundVideos.length + taskVideos.length + rewardVideos.length + punishmentVideos.length;
|
||||
let totalVideos = backgroundVideos.length + taskVideos.length + rewardVideos.length + punishmentVideos.length + capturedVideos.length;
|
||||
|
||||
// If no categorized videos found but we have "all" videos, use those
|
||||
let allVideos = [];
|
||||
|
|
@ -4185,7 +4186,32 @@
|
|||
`;
|
||||
videoGallery.appendChild(videoElement);
|
||||
});
|
||||
|
||||
// Add captured session videos
|
||||
const capturedVideos = JSON.parse(localStorage.getItem('capturedVideos') || '[]');
|
||||
console.log(`📹 Found ${capturedVideos.length} captured session videos`);
|
||||
|
||||
capturedVideos.forEach((video, index) => {
|
||||
const date = new Date(video.timestamp);
|
||||
const duration = formatVideoDuration(video.duration);
|
||||
const videoElement = document.createElement('div');
|
||||
videoElement.className = 'gallery-item captured-video-item';
|
||||
videoElement.innerHTML = `
|
||||
<div class="video-info">
|
||||
<div class="video-icon">📹</div>
|
||||
<div class="video-name">Session Recording ${index + 1}</div>
|
||||
<div class="video-type">Captured Video</div>
|
||||
<div class="video-meta">${date.toLocaleDateString()} - ${duration}</div>
|
||||
</div>
|
||||
<div class="video-actions">
|
||||
<button class="btn-small" onclick="playCapturedVideo('${video.id}')">▶️ Play</button>
|
||||
<button class="btn-small" onclick="downloadCapturedVideo('${video.id}')">💾 Download</button>
|
||||
<button class="btn-small btn-danger" onclick="deleteCapturedVideo('${video.id}')">🗑️ Delete</button>
|
||||
</div>
|
||||
`;
|
||||
videoGallery.appendChild(videoElement);
|
||||
});
|
||||
|
||||
// If no categorized videos were added but we have uncategorized videos, add those
|
||||
if (videoGallery.children.length === 0 && allVideos.length > 0) {
|
||||
allVideos.forEach((video, index) => {
|
||||
|
|
@ -4590,6 +4616,99 @@
|
|||
}
|
||||
}
|
||||
|
||||
// Captured Video Functions
|
||||
function formatVideoDuration(ms) {
|
||||
const seconds = Math.floor(ms / 1000);
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const remainingSeconds = seconds % 60;
|
||||
return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
function playCapturedVideo(videoId) {
|
||||
const capturedVideos = JSON.parse(localStorage.getItem('capturedVideos') || '[]');
|
||||
const video = capturedVideos.find(v => v.id === videoId);
|
||||
|
||||
if (!video) {
|
||||
console.warn('Video not found:', videoId);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create fullscreen video player
|
||||
const overlay = document.createElement('div');
|
||||
overlay.className = 'video-player-overlay';
|
||||
overlay.style.cssText = `
|
||||
position: fixed; top: 0; left: 0; width: 100%; height: 100vh;
|
||||
background: rgba(0,0,0,0.95); display: flex; align-items: center;
|
||||
justify-content: center; z-index: 10000;
|
||||
`;
|
||||
|
||||
overlay.innerHTML = `
|
||||
<div class="video-player-container" style="position: relative; max-width: 90vw; max-height: 90vh;">
|
||||
<video controls autoplay style="width: 100%; height: auto; max-height: 90vh; border-radius: 10px;">
|
||||
<source src="${video.dataURL}" type="video/webm">
|
||||
</video>
|
||||
<button class="close-player" onclick="closeCapturedVideoPlayer()"
|
||||
style="position: absolute; top: -40px; right: 0; background: rgba(255,255,255,0.2);
|
||||
border: none; border-radius: 50%; width: 35px; height: 35px; color: #fff;
|
||||
font-size: 1.2rem; cursor: pointer; transition: all 0.3s ease;">✕</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.appendChild(overlay);
|
||||
window.currentCapturedVideoOverlay = overlay;
|
||||
}
|
||||
|
||||
function closeCapturedVideoPlayer() {
|
||||
if (window.currentCapturedVideoOverlay) {
|
||||
document.body.removeChild(window.currentCapturedVideoOverlay);
|
||||
window.currentCapturedVideoOverlay = null;
|
||||
}
|
||||
}
|
||||
|
||||
function downloadCapturedVideo(videoId) {
|
||||
const capturedVideos = JSON.parse(localStorage.getItem('capturedVideos') || '[]');
|
||||
const video = capturedVideos.find(v => v.id === videoId);
|
||||
|
||||
if (!video) {
|
||||
console.warn('Video not found:', videoId);
|
||||
return;
|
||||
}
|
||||
|
||||
const a = document.createElement('a');
|
||||
a.href = video.dataURL;
|
||||
a.download = `quick-play-session-${new Date(video.timestamp).toISOString().slice(0, 19).replace(/:/g, '-')}.webm`;
|
||||
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
|
||||
console.log('📹 Video downloaded:', videoId);
|
||||
|
||||
if (window.game && window.game.flashMessageManager) {
|
||||
window.game.flashMessageManager.show('📹 Video downloaded successfully!', 'info');
|
||||
}
|
||||
}
|
||||
|
||||
function deleteCapturedVideo(videoId) {
|
||||
if (!confirm('⚠️ Are you sure you want to delete this video? This cannot be undone.')) {
|
||||
return;
|
||||
}
|
||||
|
||||
let capturedVideos = JSON.parse(localStorage.getItem('capturedVideos') || '[]');
|
||||
capturedVideos = capturedVideos.filter(v => v.id !== videoId);
|
||||
|
||||
localStorage.setItem('capturedVideos', JSON.stringify(capturedVideos));
|
||||
|
||||
console.log('🗑️ Video deleted:', videoId);
|
||||
|
||||
// Refresh the video library
|
||||
setupLibraryVideoTab();
|
||||
|
||||
if (window.game && window.game.flashMessageManager) {
|
||||
window.game.flashMessageManager.show('🗑️ Video deleted successfully!', 'info');
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize bulk action event listeners
|
||||
function initializeBulkActions() {
|
||||
const selectAllBtn = document.getElementById('select-all-photos');
|
||||
|
|
|
|||
|
|
@ -4607,16 +4607,16 @@
|
|||
}
|
||||
};
|
||||
|
||||
// Save to localStorage gallery
|
||||
let savedVideos = JSON.parse(localStorage.getItem('savedSessionVideos') || '[]');
|
||||
savedVideos.push(videoData);
|
||||
// Save to localStorage gallery (same pattern as photos)
|
||||
let capturedVideos = JSON.parse(localStorage.getItem('capturedVideos') || '[]');
|
||||
capturedVideos.push(videoData);
|
||||
|
||||
// Keep only last 10 recordings to manage storage
|
||||
if (savedVideos.length > 10) {
|
||||
savedVideos = savedVideos.slice(-10);
|
||||
if (capturedVideos.length > 10) {
|
||||
capturedVideos = capturedVideos.slice(-10);
|
||||
}
|
||||
|
||||
localStorage.setItem('savedSessionVideos', JSON.stringify(savedVideos));
|
||||
localStorage.setItem('capturedVideos', JSON.stringify(capturedVideos));
|
||||
|
||||
console.log('✅ Session recording saved to gallery:', videoData.id);
|
||||
|
||||
|
|
@ -4653,11 +4653,11 @@
|
|||
}
|
||||
|
||||
function loadSessionVideos() {
|
||||
const savedVideos = JSON.parse(localStorage.getItem('savedSessionVideos') || '[]');
|
||||
const capturedVideos = JSON.parse(localStorage.getItem('capturedVideos') || '[]');
|
||||
const videosGrid = document.getElementById('videos-grid');
|
||||
const noVideosMessage = document.getElementById('no-videos-message');
|
||||
|
||||
if (savedVideos.length === 0) {
|
||||
if (capturedVideos.length === 0) {
|
||||
videosGrid.innerHTML = '';
|
||||
noVideosMessage.style.display = 'block';
|
||||
return;
|
||||
|
|
@ -4666,9 +4666,9 @@
|
|||
noVideosMessage.style.display = 'none';
|
||||
|
||||
// Sort by timestamp (newest first)
|
||||
savedVideos.sort((a, b) => b.timestamp - a.timestamp);
|
||||
capturedVideos.sort((a, b) => b.timestamp - a.timestamp);
|
||||
|
||||
videosGrid.innerHTML = savedVideos.map(video => {
|
||||
videosGrid.innerHTML = capturedVideos.map(video => {
|
||||
const date = new Date(video.timestamp);
|
||||
const duration = formatDuration(video.duration);
|
||||
|
||||
|
|
@ -4713,8 +4713,8 @@
|
|||
}
|
||||
|
||||
function playVideo(videoId) {
|
||||
const savedVideos = JSON.parse(localStorage.getItem('savedSessionVideos') || '[]');
|
||||
const video = savedVideos.find(v => v.id === videoId);
|
||||
const capturedVideos = JSON.parse(localStorage.getItem('capturedVideos') || '[]');
|
||||
const video = capturedVideos.find(v => v.id === videoId);
|
||||
|
||||
if (!video) {
|
||||
console.warn('Video not found:', videoId);
|
||||
|
|
@ -4745,8 +4745,8 @@
|
|||
}
|
||||
|
||||
function downloadVideo(videoId) {
|
||||
const savedVideos = JSON.parse(localStorage.getItem('savedSessionVideos') || '[]');
|
||||
const video = savedVideos.find(v => v.id === videoId);
|
||||
const capturedVideos = JSON.parse(localStorage.getItem('capturedVideos') || '[]');
|
||||
const video = capturedVideos.find(v => v.id === videoId);
|
||||
|
||||
if (!video) {
|
||||
console.warn('Video not found:', videoId);
|
||||
|
|
@ -4773,10 +4773,10 @@
|
|||
return;
|
||||
}
|
||||
|
||||
let savedVideos = JSON.parse(localStorage.getItem('savedSessionVideos') || '[]');
|
||||
savedVideos = savedVideos.filter(v => v.id !== videoId);
|
||||
let capturedVideos = JSON.parse(localStorage.getItem('capturedVideos') || '[]');
|
||||
capturedVideos = capturedVideos.filter(v => v.id !== videoId);
|
||||
|
||||
localStorage.setItem('savedSessionVideos', JSON.stringify(savedVideos));
|
||||
localStorage.setItem('capturedVideos', JSON.stringify(capturedVideos));
|
||||
|
||||
console.log('🗑️ Video deleted:', videoId);
|
||||
|
||||
|
|
@ -4789,7 +4789,7 @@
|
|||
}
|
||||
|
||||
function clearAllSessionVideos() {
|
||||
localStorage.removeItem('savedSessionVideos');
|
||||
localStorage.removeItem('capturedVideos');
|
||||
loadSessionVideos();
|
||||
|
||||
console.log('🗑️ All session videos cleared');
|
||||
|
|
|
|||
Loading…
Reference in New Issue