Explorar o código

Improve Now Playing Bar positioning and add favorite to pattern panel

- Fix Now Playing Bar position calculation when logs drawer is open
- Pass dynamic logsDrawerHeight instead of hardcoded value
- Add vertical padding to collapsed bar content
- Adjust bar heights for better spacing
- Add favorite toggle button in pattern details panel header
- Add env vars for testing update functionality

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
tuanchris hai 2 semanas
pai
achega
46be689ae3

+ 4 - 0
docker-compose.yml

@@ -23,6 +23,10 @@ services:
     restart: always
     ports:
       - "8080:8080"
+    environment:
+      # Testing overrides (uncomment to enable):
+      # FORCE_UPDATE_AVAILABLE: "1"        # Always show update available
+      # FAKE_LATEST_VERSION: "99.0.0"      # Fake a newer version
     volumes:
       # Mount entire app directory for persistence
       - .:/app

+ 4 - 3
frontend/src/components/NowPlayingBar.tsx

@@ -178,12 +178,13 @@ function SortableQueueItem({
 
 interface NowPlayingBarProps {
   isLogsOpen?: boolean
+  logsDrawerHeight?: number
   isVisible: boolean
   openExpanded?: boolean
   onClose: () => void
 }
 
-export function NowPlayingBar({ isLogsOpen = false, isVisible, openExpanded = false, onClose }: NowPlayingBarProps) {
+export function NowPlayingBar({ isLogsOpen = false, logsDrawerHeight = 256, isVisible, openExpanded = false, onClose }: NowPlayingBarProps) {
   const [status, setStatus] = useState<PlaybackStatus | null>(null)
   const [previewUrl, setPreviewUrl] = useState<string | null>(null)
   const wsRef = useRef<WebSocket | null>(null)
@@ -843,7 +844,7 @@ export function NowPlayingBar({ isLogsOpen = false, isVisible, openExpanded = fa
         className="fixed left-0 right-0 z-40 bg-background border-t shadow-lg transition-all duration-300"
         style={{
           bottom: isLogsOpen
-            ? 'calc(20rem + env(safe-area-inset-bottom, 0px))'
+            ? `calc(${logsDrawerHeight}px + 4rem + env(safe-area-inset-bottom, 0px))`
             : 'calc(4rem + env(safe-area-inset-bottom, 0px))'
         }}
         data-now-playing-bar={isExpanded ? 'expanded' : 'collapsed'}
@@ -899,7 +900,7 @@ export function NowPlayingBar({ isLogsOpen = false, isVisible, openExpanded = fa
           {!isExpanded && (
             <div className="flex-1 flex flex-col">
               {/* Main row with preview and controls */}
-              <div className="flex-1 flex items-center gap-6 px-6">
+              <div className="flex-1 flex items-center gap-6 px-6 py-4">
                 {/* Current Pattern Preview - Rounded (click to expand) */}
                 <div
                   className="w-48 h-48 rounded-full overflow-hidden bg-muted shrink-0 border-2 cursor-pointer hover:border-primary transition-colors"

+ 1 - 0
frontend/src/components/layout/Layout.tsx

@@ -1339,6 +1339,7 @@ export function Layout() {
       {/* Now Playing Bar */}
       <NowPlayingBar
         isLogsOpen={isLogsOpen}
+        logsDrawerHeight={logsDrawerHeight}
         isVisible={isNowPlayingOpen}
         openExpanded={openNowPlayingExpanded}
         onClose={() => setIsNowPlayingOpen(false)}

+ 2 - 2
frontend/src/index.css

@@ -175,7 +175,7 @@ body {
 
 /* Now Playing Bar heights - responsive for mobile vs desktop */
 [data-now-playing-bar="collapsed"] {
-  height: 200px;
+  height: 232px;
 }
 
 [data-now-playing-bar="expanded"] {
@@ -184,7 +184,7 @@ body {
 
 @media (max-width: 767px) {
   [data-now-playing-bar="collapsed"] {
-    height: 256px;
+    height: 288px;
   }
 
   [data-now-playing-bar="expanded"] {

+ 23 - 2
frontend/src/pages/BrowsePage.tsx

@@ -991,8 +991,29 @@ export function BrowsePage() {
       <Sheet open={isPanelOpen} onOpenChange={setIsPanelOpen}>
         <SheetContent className="flex flex-col p-0 overflow-hidden">
           <SheetHeader className="px-6 py-4 shrink-0">
-            <SheetTitle className="truncate pr-8">
-              {selectedPattern?.name || 'Pattern Details'}
+            <SheetTitle className="flex items-center gap-2 pr-8">
+              {selectedPattern && (
+                <span
+                  role="button"
+                  tabIndex={0}
+                  className={`shrink-0 transition-colors cursor-pointer flex items-center ${
+                    favorites.has(selectedPattern.path) ? 'text-red-500 hover:text-red-600' : 'text-muted-foreground hover:text-red-500'
+                  }`}
+                  onClick={(e) => toggleFavorite(selectedPattern.path, e)}
+                  onKeyDown={(e) => {
+                    if (e.key === 'Enter' || e.key === ' ') {
+                      e.preventDefault()
+                      toggleFavorite(selectedPattern.path, e as unknown as React.MouseEvent)
+                    }
+                  }}
+                  title={favorites.has(selectedPattern.path) ? 'Remove from favorites' : 'Add to favorites'}
+                >
+                  <span className="material-icons" style={{ fontSize: '20px' }}>
+                    {favorites.has(selectedPattern.path) ? 'favorite' : 'favorite_border'}
+                  </span>
+                </span>
+              )}
+              <span className="truncate">{selectedPattern?.name || 'Pattern Details'}</span>
             </SheetTitle>
           </SheetHeader>