Explorar o código

Improve Musicify touch playback behavior

Avoid touch-only hover interactions in Musicify by showing playlist, queue, and song-row controls without relying on `:hover`, while keeping desktop hover behavior unchanged. Also prevent tapping the currently loaded track from restarting playback; it now opens the Now Playing panel instead, which fixes the double-tap/restart experience on touch devices.
Toby Chui hai 2 semanas
pai
achega
73ec724d61
Modificáronse 2 ficheiros con 38 adicións e 6 borrados
  1. 30 6
      src/web/Musicify/index.html
  2. 8 0
      src/web/Musicify/musicify.js

+ 30 - 6
src/web/Musicify/index.html

@@ -131,7 +131,12 @@
             opacity: 0; font-size: 11px; color: var(--text3); padding: 2px 4px;
             border-radius: 3px; transition: opacity .12s;
         }
-        .playlist-item:hover .pl-del { opacity: 1; }
+        @media (hover: hover) {
+            .playlist-item:hover .pl-del { opacity: 1; }
+        }
+        @media (hover: none) {
+            .playlist-item .pl-del { opacity: 1; }
+        }
         .playlist-item .pl-del:hover { color: #f87171; }
         .playlist-item i { margin-bottom: 5px !important; }
         .new-playlist-btn {
@@ -252,14 +257,22 @@
             transition: background .1s;
             color: var(--text2);
         }
-        .song-row:hover  { background: var(--hover); color: var(--text); }
+        /* Hover-reveal effects are gated to real pointer devices. On a touch screen a
+           :hover rule that swaps content makes the browser treat the first tap as a
+           hover and swallow the click, so the row needs a second tap to actually fire.
+           Kept in source order so the .active rules still win on equal specificity. */
+        @media (hover: hover) {
+            .song-row:hover  { background: var(--hover); color: var(--text); }
+        }
         .song-row.active { background: var(--active-bg); color: var(--accent); }
         .song-row.active .song-name { color: var(--accent); }
 
         .song-idx  { font-size: 12px; color: var(--text3); text-align: right; }
         .song-play { display: none; font-size: 14px; color: var(--accent); text-align: center; }
-        .song-row:hover .song-idx  { display: none; }
-        .song-row:hover .song-play { display: block; }
+        @media (hover: hover) {
+            .song-row:hover .song-idx  { display: none; }
+            .song-row:hover .song-play { display: block; }
+        }
         .song-row.active .song-idx  { display: none; }
         .song-row.active .song-play { display: block; }
 
@@ -279,7 +292,13 @@
         .song-artist{ font-size: 12px; color: var(--text2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
         .song-size  { font-size: 12px; color: var(--text3); text-align: right; white-space: nowrap; }
         .song-menu  { font-size: 16px; color: var(--text3); text-align: center; opacity: 0; transition: opacity .12s; position: relative; }
-        .song-row:hover .song-menu { opacity: 1; }
+        @media (hover: hover) {
+            .song-row:hover .song-menu { opacity: 1; }
+        }
+        /* No hover on touch, so keep the row menu permanently visible instead. */
+        @media (hover: none) {
+            .song-menu { opacity: 1; }
+        }
 
         @media (max-width: 768px) {
             .song-row,
@@ -375,7 +394,12 @@
         .queue-item-name { font-size: 12.5px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); }
         .queue-item-artist{ font-size: 11px; color: var(--text2); }
         .queue-item-del { opacity: 0; font-size: 12px; color: var(--text3); transition: opacity .12s; flex-shrink: 0; cursor: pointer; }
-        .queue-item:hover .queue-item-del { opacity: 1; }
+        @media (hover: hover) {
+            .queue-item:hover .queue-item-del { opacity: 1; }
+        }
+        @media (hover: none) {
+            .queue-item-del { opacity: 1; }
+        }
         .queue-item-del:hover { color: #f87171; }
 
         @media (max-width: 900px) {

+ 8 - 0
src/web/Musicify/musicify.js

@@ -934,6 +934,14 @@ function musicifyApp() {
 
         playSong(song, sourceList, event) {
             if (event) event.stopPropagation();
+            // Re-selecting the track that is already loaded shouldn't restart it from
+            // the beginning — surface the Now Playing panel (album art / visualizer)
+            // instead. Keyed on isCurrentTrack so the row highlighted as .active is
+            // exactly the row that opens the panel, paused or playing.
+            if (this.isCurrentTrack(song)) {
+                this.openNowPlaying();
+                return;
+            }
             if (!sourceList || sourceList.length === 0) sourceList = [song];
             var idx = 0;
             for (var i = 0; i < sourceList.length; i++) {