feat: Add conditional iframe refresh button for animated HTML ads

- Add ReloadOutlined icon import for refresh functionality
- Implement handleRefreshAd() to reload iframes with cache-busting timestamps
- Add refresh button next to share button with consistent styling
- Show refresh button only for ads containing HTML files (iframe content)
- Add user feedback messages for successful refresh operations
- Prevent unnecessary refresh buttons on image-only or video-only ads

HTML ads with animations can now be restarted without full page reload.
Button appears conditionally based on file type detection.
This commit is contained in:
Johannes
2025-09-14 15:54:39 +02:00
parent 71b4d3f845
commit d465fbeb94
2 changed files with 38 additions and 8 deletions

View File

@@ -58,13 +58,6 @@ export default function UserMenu({ user, onLogout, darkMode, onToggleDarkMode, s
onClick: clearAdsCache,
},
{ type: 'divider' },
{
key: 'settings',
icon: <SettingOutlined />,
label: 'Einstellungen (bald)',
disabled: true,
},
{ type: 'divider' },
{
key: 'logout',
icon: <LogoutOutlined />,

View File

@@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { Tabs, Button, Spin, Skeleton, Result, Grid, Select, Layout, Tooltip, message } from 'antd';
import { ArrowLeftOutlined, LoadingOutlined, LockOutlined, MinusOutlined, PlusOutlined, EllipsisOutlined, ShareAltOutlined } from '@ant-design/icons';
import { ArrowLeftOutlined, LoadingOutlined, LockOutlined, MinusOutlined, PlusOutlined, EllipsisOutlined, ShareAltOutlined, ReloadOutlined } from '@ant-design/icons';
import UserMenu from '../components/UserMenu';
import FilePreview, { formatFileSize, formatDuration } from '../components/FilePreview';
import debugLogger from '../utils/debugLogger';
@@ -85,6 +85,32 @@ function ProjectDetail({ user, darkMode, onLogout, onToggleDarkMode, overridePar
}
};
// iFrame Refresh Funktionalität
const handleRefreshAd = (adId, adName) => {
// Finde alle iFrames innerhalb des Ad-Containers
const adContainer = document.getElementById(adId);
if (adContainer) {
const iframes = adContainer.querySelectorAll('iframe');
let refreshedCount = 0;
iframes.forEach((iframe) => {
if (iframe.src) {
// Füge einen Timestamp als URL-Parameter hinzu, um den Cache zu umgehen
const url = new URL(iframe.src);
url.searchParams.set('refresh', Date.now().toString());
iframe.src = url.toString();
refreshedCount++;
}
});
if (refreshedCount > 0) {
message.success(`Animation${refreshedCount > 1 ? 'en' : ''} "${adName}" ${refreshedCount > 1 ? 'wurden' : 'wurde'} neu geladen!`);
} else {
message.info(`Keine Animationen in "${adName}" gefunden.`);
}
}
};
useEffect(() => {
async function fetchLogo() {
if (!client || !project) {
@@ -153,6 +179,17 @@ function ProjectDetail({ user, darkMode, onLogout, onToggleDarkMode, overridePar
onClick={() => handleCopyLink(adId, ad.name)}
/>
</Tooltip>
{/* Refresh-Button nur bei HTML-Dateien (iFrames) anzeigen */}
{Array.isArray(ad.files) && ad.files.some(file => file.type === 'html') && (
<Tooltip title="Animationen neu laden">
<Button
type="text"
shape="circle"
icon={<ReloadOutlined />}
onClick={() => handleRefreshAd(adId, ad.name)}
/>
</Tooltip>
)}
</div>
{/* Dateien unterhalb des Ads anzeigen */}
{Array.isArray(ad.files) && ad.files.length > 0 ? (