Add swipe gestures, source links, and scalable dots to car mode

- Add touch swipe support for navigating between news cards
- Remove prev/next arrow buttons (replaced by swipe)
- Add source article link buttons below each card
- Scale card counter dots to fit within viewport width

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-28 20:58:09 +00:00
parent e62ac1d844
commit 4224064f83

View File

@@ -256,10 +256,18 @@ function renderCarModeCard(group, index, total) {
<div class="car-mode-progress h-full bg-yellow-400"></div>
</div>
</div>
<!-- Source article links -->
<div class="flex items-center justify-center gap-2 sm:gap-3 mt-3 mb-2 z-20">
${group.articles.slice(0, 5).map((article, i) => `
<a href="${article.link}" target="_blank" rel="noopener noreferrer" class="px-3 py-1.5 sm:px-4 sm:py-2 text-sm sm:text-base font-medium text-white/80 hover:text-white bg-white/10 hover:bg-white/20 rounded-full transition-colors backdrop-blur-sm" title="${article.title} (${article.source})">
Link ${i + 1}
</a>
`).join('')}
</div>
<!-- Card counter -->
<div class="absolute bottom-6 sm:bottom-8 left-1/2 -translate-x-1/2 flex items-center gap-2 z-30">
<div class="absolute bottom-6 sm:bottom-8 left-1/2 -translate-x-1/2 flex items-center justify-center z-30 max-w-[90vw] px-4">
${Array.from({ length: total }, (_, i) => `
<div class="w-2 h-2 rounded-full transition-all duration-300 ${i === index ? 'bg-white w-6' : 'bg-white/40'}"></div>
<div class="shrink-0 rounded-full transition-all duration-300 ${i === index ? 'bg-white' : 'bg-white/40'}" style="width: ${i === index ? Math.max(12, Math.min(24, 200 / total)) : Math.max(6, Math.min(8, 120 / total))}px; height: ${Math.max(6, Math.min(8, 120 / total))}px; margin: 0 ${Math.max(2, Math.min(4, 60 / total))}px;"></div>
`).join('')}
</div>
`
@@ -321,20 +329,6 @@ function renderCarMode() {
<!-- Card Container -->
<div class="relative z-10 flex flex-col items-center w-full h-full pt-16">
${renderCarModeCard(currentGroup, state.carModeIndex, state.groups.length)}
<!-- Navigation buttons moved below card -->
<div class="flex items-center gap-12 mt-4 sm:mt-6 z-20">
<button onclick="carModePrev()" class="p-4 text-white/70 hover:text-white hover:bg-white/10 rounded-full transition-colors backdrop-blur-sm bg-black/10" title="Previous">
<svg class="w-8 h-8 sm:w-10 sm:h-10" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
</svg>
</button>
<button onclick="carModeNext()" class="p-4 text-white/70 hover:text-white hover:bg-white/10 rounded-full transition-colors backdrop-blur-sm bg-black/10" title="Next">
<svg class="w-8 h-8 sm:w-10 sm:h-10" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
</svg>
</button>
</div>
</div>
</div>
`
@@ -721,6 +715,42 @@ document.addEventListener('keydown', (e) => {
}
})
// Touch/swipe support for car mode
let touchStartX = 0
let touchStartY = 0
let touchEndX = 0
let touchEndY = 0
document.addEventListener('touchstart', (e) => {
if (!state.carMode) return
touchStartX = e.changedTouches[0].screenX
touchStartY = e.changedTouches[0].screenY
}, { passive: true })
document.addEventListener('touchend', (e) => {
if (!state.carMode) return
touchEndX = e.changedTouches[0].screenX
touchEndY = e.changedTouches[0].screenY
handleSwipe()
}, { passive: true })
function handleSwipe() {
const deltaX = touchEndX - touchStartX
const deltaY = touchEndY - touchStartY
const minSwipeDistance = 50
// Only register as horizontal swipe if horizontal movement is greater than vertical
if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > minSwipeDistance) {
if (deltaX < 0) {
// Swiped left - go to next card
window.carModeNext()
} else {
// Swiped right - go to previous card
window.carModePrev()
}
}
}
// Initialize: either start car mode or fetch regular news
if (isCarModeUrl) {
// On dedicated car mode URL, directly enter car mode