fix: grid minmax, media polling fallback, content webview layout, swipe timeout

This commit is contained in:
2026-08-16 20:25:21 +08:00
parent 8d10d9e5e9
commit 7a28e2372c
5 changed files with 59 additions and 10 deletions
+16 -5
View File
@@ -126,7 +126,7 @@ body {
flex: 1;
min-height: 0;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-columns: repeat(3, minmax(0, 1fr));
grid-auto-rows: 1fr;
gap: 16px;
padding: 16px;
@@ -172,7 +172,7 @@ body {
}
.time-card .big {
font-size: 56px;
font-size: clamp(26px, 3.5vw, 52px);
font-weight: 300;
line-height: 1;
/* 等宽数字:1 和 0 等宽,避免时间刷新时卡片宽度抖动 */
@@ -275,9 +275,8 @@ body {
margin-top: 2px;
font-size: 13px;
color: var(--text-dim);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
white-space: normal;
word-break: break-word;
}
/* 进度条 */
@@ -298,6 +297,18 @@ body {
transition: width .3s linear;
}
/* 无时长信息时的活动脉冲进度条 */
/* Indeterminate pulse when no duration is available */
.media-card .bar.indeterminate {
width: 40%;
animation: bar-pulse 1.5s ease-in-out infinite;
}
@keyframes bar-pulse {
0%, 100% { transform: translateX(0); }
50% { transform: translateX(150%); }
}
/* 控制按钮:SVG 图标 + 按压动画 */
/* Controls: SVG icons + press animation */
.media-card .controls {
+13 -3
View File
@@ -192,7 +192,13 @@ function startMediaTicker() {
const bar = document.querySelector('.media-card .bar');
if (!bar || !mediaProgressState) return;
const { position, duration, playing, updatedAt } = mediaProgressState;
if (!duration) return;
if (!duration) {
// 无时长信息(部分 App 不提供 duration):显示活动脉冲而非空白
// No duration (some apps omit it): show an indeterminate pulse instead of blank
bar.classList.add('indeterminate');
return;
}
bar.classList.remove('indeterminate');
const pos = playing ? position + (Date.now() - updatedAt) : position;
bar.style.width = Math.min(100, (pos / duration) * 100) + '%';
}, 1000);
@@ -242,11 +248,15 @@ function switchMedia(delta) {
const outClass = delta > 0 ? 'slide-out-left' : 'slide-out-right';
const inClass = delta > 0 ? 'slide-in-right' : 'slide-in-left';
old.classList.add(outClass);
old.addEventListener('animationend', () => {
// 用 setTimeout 替代 animationend(更可靠,避免动画事件丢失导致"只能划一次")
// Use setTimeout instead of animationend (more reliable, avoids the "swipe once
// then stuck" issue when the animation event is lost)
setTimeout(() => {
if (!old.isConnected) return;
const fresh = renderMediaCard(info);
fresh.classList.add(inClass);
old.replaceWith(fresh);
}, { once: true });
}, 180);
}
// 转义 HTML 特殊字符,避免媒体元数据注入标签