Add privacy toggle to blur media on generate and gallery pages
All checks were successful
Build and Push Frontend Docker Image / build (push) Successful in 30s

- Add "Hide Media" / "Show Media" button to both sections
- Blur images and videos when privacy mode is active
- Persist privacy preference in localStorage per section

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Debian
2026-01-08 00:36:28 +00:00
parent ff54cf7363
commit 55af3da1ae
3 changed files with 56 additions and 0 deletions

View File

@@ -666,3 +666,29 @@ body {
text-align: center;
}
}
/* Privacy Mode */
.privacy-toggle.active {
background: var(--primary);
color: white;
}
.privacy-mode .preview-image,
.privacy-mode .output-video,
.privacy-mode .gallery-item-media video,
.privacy-mode .gallery-item-media img {
filter: blur(20px);
transition: filter 0.3s ease;
}
.privacy-mode .gallery-item-media::after {
content: 'Hidden';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-weight: 500;
text-shadow: 0 1px 3px rgba(0,0,0,0.5);
pointer-events: none;
}

View File

@@ -74,6 +74,10 @@
<main class="main-content">
<!-- Generate Section -->
<section id="generate-section" class="content-section">
<div class="section-header">
<h2>Generate</h2>
<button id="generate-privacy-toggle" class="btn btn-sm btn-secondary privacy-toggle">Hide Media</button>
</div>
<div class="section-grid">
<div class="card">
<h2>Input Image</h2>
@@ -131,6 +135,7 @@
<div class="section-header">
<h2>My Videos</h2>
<div class="filter-group">
<button id="gallery-privacy-toggle" class="btn btn-sm btn-secondary privacy-toggle">Hide Media</button>
<select id="status-filter">
<option value="">All Status</option>
<option value="completed">Completed</option>

View File

@@ -722,5 +722,30 @@ function bufferToBase64Url(buffer) {
return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}
// Privacy Toggle
function setupPrivacyToggle(buttonId, sectionId) {
const btn = document.getElementById(buttonId);
const section = document.getElementById(sectionId);
if (!btn || !section) return;
// Restore state from localStorage
const storageKey = `privacy-${sectionId}`;
if (localStorage.getItem(storageKey) === 'true') {
section.classList.add('privacy-mode');
btn.classList.add('active');
btn.textContent = 'Show Media';
}
btn.addEventListener('click', () => {
const isPrivate = section.classList.toggle('privacy-mode');
btn.classList.toggle('active', isPrivate);
btn.textContent = isPrivate ? 'Show Media' : 'Hide Media';
localStorage.setItem(storageKey, isPrivate);
});
}
setupPrivacyToggle('generate-privacy-toggle', 'generate-section');
setupPrivacyToggle('gallery-privacy-toggle', 'gallery-section');
// Init
checkAuth();