diff --git a/app/src/main/assets/h5/css/app.css b/app/src/main/assets/h5/css/app.css
index ed69d39..c82b266 100644
--- a/app/src/main/assets/h5/css/app.css
+++ b/app/src/main/assets/h5/css/app.css
@@ -143,6 +143,7 @@ body {
/* Cards stretch to fill the column height (even split when multiple) */
flex: 1 1 0;
min-height: 0;
+ min-width: 0; /* 防止内容(长标题/歌词)撑开 Grid 列宽 */
background: var(--glass-bg);
backdrop-filter: var(--blur-filter);
-webkit-backdrop-filter: var(--blur-filter);
@@ -151,6 +152,13 @@ body {
border-radius: 14px;
padding: 20px;
color: var(--text);
+ transition: transform .18s ease;
+}
+
+/* 卡片非交互区域的触摸按压反馈:轻微缩放,避免生硬 */
+/* Touch/press feedback on the card's non-interactive area: subtle scale */
+.card:active {
+ transform: scale(0.985);
}
/* 大字时间卡:主时间大字 + 日期副行 */
@@ -188,28 +196,79 @@ body {
color: var(--text-dim);
}
-/* 媒体卡:flex column,标题靠上、进度/控制靠下 */
-/* Media card: flex column, title top, progress/controls bottom */
+/* 媒体卡:flex column,信息区靠上、进度/控制靠下 */
+/* Media card: flex column, info top, progress/controls bottom */
.media-card {
display: flex;
flex-direction: column;
+ overflow: hidden;
}
-/* 媒体卡:正在播放标签 + 标题/艺术家 + 进度条 */
-/* Media card: playing caption + title/artist + progress bar */
-.media-card .cap {
- font-size: 11px;
- color: var(--text-dim);
- letter-spacing: 1px;
+/* 媒体卡布局:默认上下(封面在上、信息在下),横条时左右(.wide) */
+/* Media layout: vertical (cover on top, info below) by default; horizontal
+ (cover left, info right) when the card is wider than tall (.wide) */
+.media-card .media-layout {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 12px;
+ flex: 1;
+ min-height: 0;
+ text-align: center;
}
+.media-card.wide .media-layout {
+ flex-direction: row;
+ text-align: left;
+}
+
+/* 封面:自适应,随卡片变大;可点击跳转播放界面 */
+/* Cover: adaptive size, grows with the card; tappable to open the playback UI */
+.media-card .cover {
+ width: 96px;
+ height: 96px;
+ max-width: 100%;
+ border-radius: 16px;
+ object-fit: cover;
+ flex: none;
+ cursor: pointer;
+ transition: transform .18s ease;
+}
+
+.media-card .cover:active {
+ transform: scale(0.92);
+}
+
+.media-card .cover-ph {
+ background: linear-gradient(135deg, rgba(255, 255, 255, .15), rgba(255, 255, 255, .05));
+}
+
+.media-card.wide .cover {
+ width: 120px;
+ height: 120px;
+}
+
+/* 信息区 */
+/* Info area */
+.media-card .media-info {
+ flex: 1;
+ min-width: 0;
+ min-height: 0;
+ overflow: hidden;
+}
+
+/* 标题:自动换行(歌词/长标题),最多 3 行省略 */
+/* Title: wraps automatically (lyrics / long titles), max 3 lines with ellipsis */
.media-card .tt {
margin-top: 6px;
font-size: 18px;
font-weight: 600;
+ white-space: normal;
+ word-break: break-word;
+ display: -webkit-box;
+ -webkit-line-clamp: 3;
+ -webkit-box-orient: vertical;
overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
}
.media-card .ar {
@@ -221,27 +280,8 @@ body {
white-space: nowrap;
}
-/* 媒体卡:封面 + 信息横排 */
-/* Media card: cover + info row */
-.media-card .media-row {
- display: flex;
- gap: 12px;
- align-items: center;
-}
-
-.media-card .cover {
- width: 56px;
- height: 56px;
- border-radius: 12px;
- object-fit: cover;
- flex: none;
-}
-
-.media-card .media-info {
- flex: 1;
- min-width: 0;
-}
-
+/* 进度条 */
+/* Progress bar */
.media-card .prog {
margin-top: auto;
padding-top: 12px;
@@ -255,34 +295,71 @@ body {
height: 100%;
border-radius: 999px;
background: var(--accent);
+ transition: width .3s linear;
}
-/* 媒体控制按钮:上一首/暂停/下一首 */
-/* Media controls: previous / play-pause / next */
+/* 控制按钮:SVG 图标 + 按压动画 */
+/* Controls: SVG icons + press animation */
.media-card .controls {
margin-top: 12px;
display: flex;
gap: 10px;
+ justify-content: center;
}
.media-card .controls button {
- width: 36px;
- height: 36px;
+ width: 40px;
+ height: 40px;
border: none;
border-radius: 999px;
background: var(--glass-border);
color: var(--text);
- font-size: 15px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
+ transition: transform .15s ease, background .15s ease, opacity .15s ease;
+}
+
+.media-card .controls button svg {
+ width: 20px;
+ height: 20px;
+}
+
+.media-card .controls button.play {
+ width: 48px;
+ height: 48px;
+ background: var(--accent);
+ color: #fff;
}
.media-card .controls button:active {
- opacity: 0.6;
+ transform: scale(0.82);
+ opacity: 0.7;
}
+/* 媒体卡横划切换的方向过渡动画 */
+/* Directional slide transitions for the media card swipe */
+@keyframes slide-out-left {
+ to { transform: translateX(-40%); opacity: 0; }
+}
+@keyframes slide-out-right {
+ to { transform: translateX(40%); opacity: 0; }
+}
+@keyframes slide-in-left {
+ from { transform: translateX(-40%); opacity: 0; }
+ to { transform: none; opacity: 1; }
+}
+@keyframes slide-in-right {
+ from { transform: translateX(40%); opacity: 0; }
+ to { transform: none; opacity: 1; }
+}
+
+.media-card.slide-out-left { animation: slide-out-left .2s ease forwards; }
+.media-card.slide-out-right { animation: slide-out-right .2s ease forwards; }
+.media-card.slide-in-left { animation: slide-in-left .25s ease; }
+.media-card.slide-in-right { animation: slide-in-right .25s ease; }
+
/* 安卓 APP 列表页:搜索框 + 网格 */
/* Android app list page: search box + grid */
.search { padding: 16px; }
diff --git a/app/src/main/assets/h5/js/pages/home.js b/app/src/main/assets/h5/js/pages/home.js
index c3b3038..4070967 100644
--- a/app/src/main/assets/h5/js/pages/home.js
+++ b/app/src/main/assets/h5/js/pages/home.js
@@ -103,6 +103,13 @@ function startTimeCardTicker() {
let currentMediaList = null;
let currentMediaIndex = 0;
+// SVG 控制图标(fill=currentColor,替代 emoji)
+// SVG control icons (fill=currentColor, replacing emoji)
+const ICON_PREV = '';
+const ICON_PLAY = '';
+const ICON_PAUSE = '';
+const ICON_NEXT = '';
+
// 原生媒体会话事件:接收会话列表,有媒体时渲染媒体卡,无媒体时降级
// Native media session event: receives the session list; render media card when
// present, otherwise fall back to re-layout
@@ -111,9 +118,11 @@ window.HearthEvents.mediaSessionChanged = function (infos) {
if (!infos || infos.length === 0) {
currentMediaList = null;
currentMediaIndex = 0;
+ mediaProgressState = null;
} else {
currentMediaList = infos;
if (currentMediaIndex >= infos.length) currentMediaIndex = 0;
+ updateMediaProgressState(infos[currentMediaIndex]);
}
const grid = document.getElementById('tri-col');
if (!grid) return;
@@ -127,11 +136,12 @@ function renderMediaCard(info) {
el.className = 'card media-card';
const coverHtml = info.cover
? ``
- : '';
+ : '