Просмотр исходного кода

Improve UI consistency and responsiveness

- Browse page: Add gap between icons and text in filter dropdowns
- NowPlayingBar: Make real-time preview responsive (42vh on desktop,
  capped at 500px), increase vertical padding
- PlaylistsPage: Restyle pattern picker modal filters to match Browse
  page (pill-shaped buttons, icon-only on mobile, consistent order:
  folder → sort → direction)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
tuanchris 2 недель назад
Родитель
Сommit
b2c0cb9ed0

+ 2 - 2
frontend/src/components/NowPlayingBar.tsx

@@ -1085,7 +1085,7 @@ export function NowPlayingBar({ isLogsOpen = false, isVisible, openExpanded = fa
 
           {/* Expanded view - Real-time canvas preview */}
           {isExpanded && isPlaying && (
-            <div className="flex-1 flex flex-col md:items-center md:justify-center px-4 py-2 md:py-4 overflow-hidden">
+            <div className="flex-1 flex flex-col md:items-center md:justify-center px-4 py-4 md:py-8 overflow-hidden">
               <div className="w-full max-w-5xl mx-auto flex flex-col md:flex-row md:items-center md:justify-center gap-3 md:gap-6">
                 {/* Canvas - full width on mobile (click to collapse) */}
                 <div
@@ -1097,7 +1097,7 @@ export function NowPlayingBar({ isLogsOpen = false, isVisible, openExpanded = fa
                     ref={canvasRef}
                     width={600}
                     height={600}
-                    className="rounded-full border-2 hover:border-primary transition-colors max-h-[40vh] max-w-[40vh] w-[40vh] h-[40vh] md:w-[300px] md:h-[300px] md:max-w-none md:max-h-none"
+                    className="rounded-full border-2 hover:border-primary transition-colors w-[40vh] h-[40vh] max-w-[300px] max-h-[300px] md:w-[42vh] md:h-[42vh] md:max-w-[500px] md:max-h-[500px]"
                   />
                 </div>
 

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

@@ -874,7 +874,7 @@ export function BrowsePage() {
 
           {/* Category - Icon on mobile, text on desktop */}
           <Select value={selectedCategory} onValueChange={setSelectedCategory}>
-            <SelectTrigger className="h-9 w-9 sm:h-11 sm:w-auto rounded-full bg-card border-border shadow-sm text-xs sm:text-sm shrink-0 [&>svg]:hidden sm:[&>svg]:block px-0 sm:px-3 justify-center sm:justify-between [&>span:last-of-type]:hidden sm:[&>span:last-of-type]:inline">
+            <SelectTrigger className="h-9 w-9 sm:h-11 sm:w-auto rounded-full bg-card border-border shadow-sm text-xs sm:text-sm shrink-0 [&>svg]:hidden sm:[&>svg]:block px-0 sm:px-3 justify-center sm:justify-between [&>span:last-of-type]:hidden sm:[&>span:last-of-type]:inline gap-2">
               <span className="material-icons-outlined text-lg shrink-0 sm:hidden">folder</span>
               <SelectValue placeholder="All" />
             </SelectTrigger>
@@ -889,7 +889,7 @@ export function BrowsePage() {
 
           {/* Sort - Icon on mobile, text on desktop */}
           <Select value={sortBy} onValueChange={(v) => setSortBy(v as SortOption)}>
-            <SelectTrigger className="h-9 w-9 sm:h-11 sm:w-auto rounded-full bg-card border-border shadow-sm text-xs sm:text-sm shrink-0 [&>svg]:hidden sm:[&>svg]:block px-0 sm:px-3 justify-center sm:justify-between [&>span:last-of-type]:hidden sm:[&>span:last-of-type]:inline">
+            <SelectTrigger className="h-9 w-9 sm:h-11 sm:w-auto rounded-full bg-card border-border shadow-sm text-xs sm:text-sm shrink-0 [&>svg]:hidden sm:[&>svg]:block px-0 sm:px-3 justify-center sm:justify-between [&>span:last-of-type]:hidden sm:[&>span:last-of-type]:inline gap-2">
               <span className="material-icons-outlined text-lg shrink-0 sm:hidden">sort</span>
               <SelectValue placeholder="Sort" />
             </SelectTrigger>

+ 44 - 44
frontend/src/pages/PlaylistsPage.tsx

@@ -872,55 +872,55 @@ export function PlaylistsPage() {
               )}
             </div>
 
-            <div className="flex flex-wrap gap-3 items-center p-3 rounded-lg bg-muted/50">
-              <div className="flex items-center gap-2">
-                <Label className="text-xs text-muted-foreground">Sort:</Label>
-                <Select value={sortBy} onValueChange={(v) => setSortBy(v as SortOption)}>
-                  <SelectTrigger className="h-8 w-28">
-                    <SelectValue />
-                  </SelectTrigger>
-                  <SelectContent>
-                    <SelectItem value="name">Name</SelectItem>
-                    <SelectItem value="date">Modified</SelectItem>
-                    <SelectItem value="size">Size</SelectItem>
-                  </SelectContent>
-                </Select>
-                <Button
-                  variant="ghost"
-                  size="icon"
-                  className="h-8 w-8"
-                  onClick={() => setSortAsc(!sortAsc)}
-                >
-                  <span className="material-icons-outlined text-lg">
-                    {sortAsc ? 'arrow_upward' : 'arrow_downward'}
-                  </span>
-                </Button>
-              </div>
-
-              <Separator orientation="vertical" className="h-6" />
-
-              <div className="flex items-center gap-2">
-                <Label className="text-xs text-muted-foreground">Folder:</Label>
-                <Select value={selectedCategory} onValueChange={setSelectedCategory}>
-                  <SelectTrigger className="h-8 w-32">
-                    <SelectValue />
-                  </SelectTrigger>
-                  <SelectContent>
-                    {categories.map(cat => (
-                      <SelectItem key={cat} value={cat}>
-                        {cat === 'all' ? 'All Folders' : cat}
-                      </SelectItem>
-                    ))}
-                  </SelectContent>
-                </Select>
-              </div>
+            <div className="flex flex-wrap gap-2 items-center">
+              {/* Folder dropdown - icon only on mobile, with text on sm+ */}
+              <Select value={selectedCategory} onValueChange={setSelectedCategory}>
+                <SelectTrigger className="h-9 w-9 sm:w-auto rounded-full bg-card border-border shadow-sm text-sm px-0 sm:px-3 justify-center sm:justify-between [&>svg]:hidden sm:[&>svg]:block [&>span:last-of-type]:hidden sm:[&>span:last-of-type]:inline gap-2">
+                  <span className="material-icons-outlined text-lg shrink-0">folder</span>
+                  <SelectValue />
+                </SelectTrigger>
+                <SelectContent>
+                  {categories.map(cat => (
+                    <SelectItem key={cat} value={cat}>
+                      {cat === 'all' ? 'All Folders' : cat}
+                    </SelectItem>
+                  ))}
+                </SelectContent>
+              </Select>
+
+              {/* Sort dropdown - icon only on mobile, with text on sm+ */}
+              <Select value={sortBy} onValueChange={(v) => setSortBy(v as SortOption)}>
+                <SelectTrigger className="h-9 w-9 sm:w-auto rounded-full bg-card border-border shadow-sm text-sm px-0 sm:px-3 justify-center sm:justify-between [&>svg]:hidden sm:[&>svg]:block [&>span:last-of-type]:hidden sm:[&>span:last-of-type]:inline gap-2">
+                  <span className="material-icons-outlined text-lg shrink-0">sort</span>
+                  <SelectValue />
+                </SelectTrigger>
+                <SelectContent>
+                  <SelectItem value="name">Name</SelectItem>
+                  <SelectItem value="date">Modified</SelectItem>
+                  <SelectItem value="size">Size</SelectItem>
+                </SelectContent>
+              </Select>
+
+              {/* Sort direction - pill shaped */}
+              <Button
+                variant="outline"
+                size="icon"
+                className="h-9 w-9 rounded-full bg-card shadow-sm"
+                onClick={() => setSortAsc(!sortAsc)}
+                title={sortAsc ? 'Ascending' : 'Descending'}
+              >
+                <span className="material-icons-outlined text-lg">
+                  {sortAsc ? 'arrow_upward' : 'arrow_downward'}
+                </span>
+              </Button>
 
               <div className="flex-1" />
 
-              <div className="flex items-center gap-2 text-sm">
+              {/* Selection count - compact on mobile */}
+              <div className="flex items-center gap-1 sm:gap-2 text-sm bg-card rounded-full px-2 sm:px-3 py-2 shadow-sm border">
                 <span className="material-icons-outlined text-base text-primary">check_circle</span>
                 <span className="font-medium">{selectedPatternPaths.size}</span>
-                <span className="text-muted-foreground">selected</span>
+                <span className="hidden sm:inline text-muted-foreground">selected</span>
               </div>
             </div>
           </div>