perf: reduce CPU usage and unify next-track buffering settings

- Throttle audio:progress from 100ms to 500ms; WaveformSeek and
  FsSeekbar use imperative DOM updates instead of React re-renders
- Fix all usePlayerStore() calls without selectors across pages and
  components (useShallow / individual selectors throughout)
- Remove filter:blur and transform:scale from Hero, AlbumDetail and
  FullscreenPlayer backgrounds — eliminated expensive software
  compositing layers on WebKitGTK
- Replace translate3d with 2D translate in FS mesh and portrait
  animations; remove will-change:transform from mesh blobs
- Move Hot Cache section from Storage tab to Audio tab; group Preload
  and Hot Cache under a shared 'Next Track Buffering' section with a
  mutual-exclusivity note and auto-disable logic
- Add 'off' toggle to Preload (replaces Off button with toggle switch);
  enabling either method now automatically disables the other

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Psychotoxical
2026-04-10 13:38:33 +02:00
parent c9dfbcc19f
commit c49f6af38b
21 changed files with 398 additions and 271 deletions
+19 -1
View File
@@ -4,6 +4,7 @@ import LastfmIcon from './LastfmIcon';
import StarRating from './StarRating';
import { lastfmLoveTrack, lastfmUnloveTrack } from '../api/lastfm';
import { usePlayerStore, Track, songToTrack } from '../store/playerStore';
import { useShallow } from 'zustand/react/shallow';
import { SubsonicAlbum, SubsonicArtist, star, unstar, getSimilarSongs2, getTopSongs, buildDownloadUrl, getAlbum, getPlaylists, getPlaylist, createPlaylist, updatePlaylist, SubsonicPlaylist, setRating } from '../api/subsonic';
import { useNavigate } from 'react-router-dom';
import { useAuthStore } from '../store/authStore';
@@ -175,7 +176,24 @@ function AlbumToPlaylistSubmenu({ albumId, onDone }: { albumId: string; onDone:
export default function ContextMenu() {
const { t } = useTranslation();
const { contextMenu, closeContextMenu, playTrack, enqueue, queue, currentTrack, removeTrack, lastfmLovedCache, setLastfmLovedForSong, starredOverrides, setStarredOverride, openSongInfo, userRatingOverrides, setUserRatingOverride } = usePlayerStore();
const { contextMenu, closeContextMenu, playTrack, enqueue, queue, currentTrack, removeTrack, lastfmLovedCache, setLastfmLovedForSong, starredOverrides, setStarredOverride, openSongInfo, userRatingOverrides, setUserRatingOverride } = usePlayerStore(
useShallow(s => ({
contextMenu: s.contextMenu,
closeContextMenu: s.closeContextMenu,
playTrack: s.playTrack,
enqueue: s.enqueue,
queue: s.queue,
currentTrack: s.currentTrack,
removeTrack: s.removeTrack,
lastfmLovedCache: s.lastfmLovedCache,
setLastfmLovedForSong: s.setLastfmLovedForSong,
starredOverrides: s.starredOverrides,
setStarredOverride: s.setStarredOverride,
openSongInfo: s.openSongInfo,
userRatingOverrides: s.userRatingOverrides,
setUserRatingOverride: s.setUserRatingOverride,
}))
);
const auth = useAuthStore();
const requestDownloadFolder = useDownloadModalStore(s => s.requestFolder);
const navigate = useNavigate();