Growth features: share buttons, NEW badge, sticky CTA, newsletter cross-promote
- Share buttons on episode and clip cards (Web Share API + clipboard fallback) - NEW badge on latest episode card - Sticky call-in CTA bar (appears after hero scrolls out) - Daily AI Briefing newsletter cross-promote in footer - Bump cache versions to v=5 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
const CLIPS_JSON_URL = '/data/clips.json';
|
||||
|
||||
const clipPlaySVG = '<svg viewBox="0 0 24 24" fill="#fff"><path d="M8 5v14l11-7z"/></svg>';
|
||||
const clipShareSVG = '<svg viewBox="0 0 24 24" fill="#fff"><path d="M16 5l-1.42 1.42-1.59-1.59V16h-2V4.83L9.42 6.42 8 5l4-4 4 4zm4 5v11a2 2 0 01-2 2H6a2 2 0 01-2-2V10a2 2 0 012-2h3v2H6v11h12V10h-3V8h3a2 2 0 012 2z"/></svg>';
|
||||
|
||||
function escapeHTML(str) {
|
||||
const el = document.createElement('span');
|
||||
@@ -8,6 +9,26 @@ function escapeHTML(str) {
|
||||
return el.innerHTML;
|
||||
}
|
||||
|
||||
async function shareClipContent(title, url, btn) {
|
||||
if (navigator.share) {
|
||||
try {
|
||||
await navigator.share({ title, url });
|
||||
return;
|
||||
} catch (e) {
|
||||
if (e.name === 'AbortError') return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
await navigator.clipboard.writeText(url);
|
||||
const orig = btn.innerHTML;
|
||||
btn.innerHTML = 'Copied!';
|
||||
btn.classList.add('share-copied');
|
||||
setTimeout(() => { btn.innerHTML = orig; btn.classList.remove('share-copied'); }, 2000);
|
||||
} catch (e) {
|
||||
prompt('Copy this link:', url);
|
||||
}
|
||||
}
|
||||
|
||||
function renderClipCard(clip, featured) {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'clip-card' + (featured ? ' clip-card-featured' : '');
|
||||
@@ -31,6 +52,7 @@ function renderClipCard(clip, featured) {
|
||||
<h3 class="clip-card-title">${title}</h3>
|
||||
<p class="clip-card-desc">${desc}</p>
|
||||
${hasVideo ? `<button class="clip-play-btn" aria-label="Play clip">${clipPlaySVG}</button>` : ''}
|
||||
${hasVideo ? `<button class="clip-share-btn" aria-label="Share clip">${clipShareSVG}</button>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -41,6 +63,13 @@ function renderClipCard(clip, featured) {
|
||||
const inner = card.querySelector('.clip-card-inner');
|
||||
inner.innerHTML = `<iframe src="https://www.youtube-nocookie.com/embed/${youtubeId}?autoplay=1&rel=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>`;
|
||||
});
|
||||
const shareBtn = card.querySelector('.clip-share-btn');
|
||||
if (shareBtn) {
|
||||
shareBtn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
shareClipContent(clip.title || '', `https://youtube.com/watch?v=${youtubeId}`, shareBtn);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return card;
|
||||
|
||||
Reference in New Issue
Block a user