|
@@ -1,6 +1,36 @@
|
|
|
import { Outlet, Link, useLocation } from 'react-router-dom'
|
|
import { Outlet, Link, useLocation } from 'react-router-dom'
|
|
|
import { useEffect, useState, useRef, useCallback } from 'react'
|
|
import { useEffect, useState, useRef, useCallback } from 'react'
|
|
|
import { toast } from 'sonner'
|
|
import { toast } from 'sonner'
|
|
|
|
|
+import {
|
|
|
|
|
+ Power,
|
|
|
|
|
+ RotateCcw,
|
|
|
|
|
+ RefreshCw,
|
|
|
|
|
+ Loader2,
|
|
|
|
|
+ CheckCircle,
|
|
|
|
|
+ Terminal,
|
|
|
|
|
+ Copy,
|
|
|
|
|
+ Eye,
|
|
|
|
|
+ EyeOff,
|
|
|
|
|
+ X,
|
|
|
|
|
+ Menu,
|
|
|
|
|
+ FileText,
|
|
|
|
|
+ Download,
|
|
|
|
|
+ HardDriveDownload,
|
|
|
|
|
+ Grid,
|
|
|
|
|
+ ListMusic,
|
|
|
|
|
+ SlidersHorizontal,
|
|
|
|
|
+ Lightbulb,
|
|
|
|
|
+ Settings as SettingsIcon,
|
|
|
|
|
+ Wifi,
|
|
|
|
|
+ WifiOff,
|
|
|
|
|
+ AlertCircle,
|
|
|
|
|
+ Home,
|
|
|
|
|
+ Sun,
|
|
|
|
|
+ Moon,
|
|
|
|
|
+ ChevronDown,
|
|
|
|
|
+ PlayCircle,
|
|
|
|
|
+ StopCircle,
|
|
|
|
|
+} from 'lucide-react'
|
|
|
import { NowPlayingBar } from '@/components/NowPlayingBar'
|
|
import { NowPlayingBar } from '@/components/NowPlayingBar'
|
|
|
import { Button } from '@/components/ui/button'
|
|
import { Button } from '@/components/ui/button'
|
|
|
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
|
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
|
@@ -12,11 +42,11 @@ import { apiClient } from '@/lib/apiClient'
|
|
|
import ShinyText from '@/components/ShinyText'
|
|
import ShinyText from '@/components/ShinyText'
|
|
|
|
|
|
|
|
const navItems = [
|
|
const navItems = [
|
|
|
- { path: '/', label: 'Browse', icon: 'grid_view', title: 'Browse Patterns' },
|
|
|
|
|
- { path: '/playlists', label: 'Playlists', icon: 'playlist_play', title: 'Playlists' },
|
|
|
|
|
- { path: '/table-control', label: 'Control', icon: 'tune', title: 'Table Control' },
|
|
|
|
|
- { path: '/led', label: 'LED', icon: 'lightbulb', title: 'LED Control' },
|
|
|
|
|
- { path: '/settings', label: 'Settings', icon: 'settings', title: 'Settings' },
|
|
|
|
|
|
|
+ { path: '/', label: 'Browse', icon: Grid, title: 'Browse Patterns' },
|
|
|
|
|
+ { path: '/playlists', label: 'Playlists', icon: ListMusic, title: 'Playlists' },
|
|
|
|
|
+ { path: '/table-control', label: 'Control', icon: SlidersHorizontal, title: 'Table Control' },
|
|
|
|
|
+ { path: '/led', label: 'LED', icon: Lightbulb, title: 'LED Control' },
|
|
|
|
|
+ { path: '/settings', label: 'Settings', icon: SettingsIcon, title: 'Settings' },
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
const DEFAULT_APP_NAME = 'Dune Weaver'
|
|
const DEFAULT_APP_NAME = 'Dune Weaver'
|
|
@@ -997,9 +1027,7 @@ export function Layout() {
|
|
|
<div className="p-6">
|
|
<div className="p-6">
|
|
|
<div className="text-center space-y-4">
|
|
<div className="text-center space-y-4">
|
|
|
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-destructive/10 mb-2">
|
|
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-destructive/10 mb-2">
|
|
|
- <span className="material-icons-outlined text-4xl text-destructive">
|
|
|
|
|
- error_outline
|
|
|
|
|
- </span>
|
|
|
|
|
|
|
+<AlertCircle className="h-10 w-10 text-destructive" />
|
|
|
</div>
|
|
</div>
|
|
|
<h2 className="text-xl font-semibold">Sensor Homing Failed</h2>
|
|
<h2 className="text-xl font-semibold">Sensor Homing Failed</h2>
|
|
|
<p className="text-muted-foreground text-sm">
|
|
<p className="text-muted-foreground text-sm">
|
|
@@ -1029,7 +1057,7 @@ export function Layout() {
|
|
|
onClick={() => handleSensorHomingRecovery(false)}
|
|
onClick={() => handleSensorHomingRecovery(false)}
|
|
|
className="w-full gap-2"
|
|
className="w-full gap-2"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons text-base">refresh</span>
|
|
|
|
|
|
|
+ <RefreshCw className="h-4 w-4" />
|
|
|
Retry Sensor Homing
|
|
Retry Sensor Homing
|
|
|
</Button>
|
|
</Button>
|
|
|
<Button
|
|
<Button
|
|
@@ -1037,7 +1065,7 @@ export function Layout() {
|
|
|
onClick={() => handleSensorHomingRecovery(true)}
|
|
onClick={() => handleSensorHomingRecovery(true)}
|
|
|
className="w-full gap-2"
|
|
className="w-full gap-2"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons text-base">sync_alt</span>
|
|
|
|
|
|
|
+ <RefreshCw className="h-4 w-4" />
|
|
|
Switch to Crash Homing
|
|
Switch to Crash Homing
|
|
|
</Button>
|
|
</Button>
|
|
|
<p className="text-xs text-muted-foreground">
|
|
<p className="text-xs text-muted-foreground">
|
|
@@ -1046,7 +1074,7 @@ export function Layout() {
|
|
|
</div>
|
|
</div>
|
|
|
) : (
|
|
) : (
|
|
|
<div className="flex items-center justify-center gap-2 py-4">
|
|
<div className="flex items-center justify-center gap-2 py-4">
|
|
|
- <span className="material-icons-outlined text-primary animate-spin">sync</span>
|
|
|
|
|
|
|
+ <Loader2 className="h-5 w-5 text-primary animate-spin" />
|
|
|
<span className="text-muted-foreground">Attempting recovery...</span>
|
|
<span className="text-muted-foreground">Attempting recovery...</span>
|
|
|
</div>
|
|
</div>
|
|
|
)}
|
|
)}
|
|
@@ -1062,9 +1090,7 @@ export function Layout() {
|
|
|
<div className="w-full max-w-md space-y-6">
|
|
<div className="w-full max-w-md space-y-6">
|
|
|
<div className="text-center space-y-4">
|
|
<div className="text-center space-y-4">
|
|
|
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-primary/10 mb-2">
|
|
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-primary/10 mb-2">
|
|
|
- <span className="material-icons-outlined text-4xl text-primary animate-pulse">
|
|
|
|
|
- cached
|
|
|
|
|
- </span>
|
|
|
|
|
|
|
+<RefreshCw className="h-10 w-10 text-primary animate-pulse" />
|
|
|
</div>
|
|
</div>
|
|
|
<h2 className="text-2xl font-bold">Initializing Pattern Cache</h2>
|
|
<h2 className="text-2xl font-bold">Initializing Pattern Cache</h2>
|
|
|
<p className="text-muted-foreground">
|
|
<p className="text-muted-foreground">
|
|
@@ -1113,9 +1139,7 @@ export function Layout() {
|
|
|
<div className="p-6">
|
|
<div className="p-6">
|
|
|
<div className="text-center space-y-4">
|
|
<div className="text-center space-y-4">
|
|
|
<div className="inline-flex items-center justify-center w-12 h-12 rounded-full bg-primary/10 mb-2">
|
|
<div className="inline-flex items-center justify-center w-12 h-12 rounded-full bg-primary/10 mb-2">
|
|
|
- <span className="material-icons-outlined text-2xl text-primary">
|
|
|
|
|
- download_for_offline
|
|
|
|
|
- </span>
|
|
|
|
|
|
|
+<HardDriveDownload className="h-6 w-6 text-primary" />
|
|
|
</div>
|
|
</div>
|
|
|
<h2 className="text-xl font-semibold">Cache All Pattern Previews?</h2>
|
|
<h2 className="text-xl font-semibold">Cache All Pattern Previews?</h2>
|
|
|
<p className="text-muted-foreground text-sm">
|
|
<p className="text-muted-foreground text-sm">
|
|
@@ -1135,7 +1159,7 @@ export function Layout() {
|
|
|
Skip for now
|
|
Skip for now
|
|
|
</Button>
|
|
</Button>
|
|
|
<Button variant="secondary" onClick={handleCacheAllPreviews} className="gap-2">
|
|
<Button variant="secondary" onClick={handleCacheAllPreviews} className="gap-2">
|
|
|
- <span className="material-icons-outlined text-lg">cached</span>
|
|
|
|
|
|
|
+ <RefreshCw className="h-5 w-5" />
|
|
|
Cache All
|
|
Cache All
|
|
|
</Button>
|
|
</Button>
|
|
|
</div>
|
|
</div>
|
|
@@ -1163,7 +1187,7 @@ export function Layout() {
|
|
|
{cacheAllProgress?.done && (
|
|
{cacheAllProgress?.done && (
|
|
|
<div className="space-y-4">
|
|
<div className="space-y-4">
|
|
|
<p className="text-green-600 dark:text-green-400 flex items-center justify-center gap-2">
|
|
<p className="text-green-600 dark:text-green-400 flex items-center justify-center gap-2">
|
|
|
- <span className="material-icons text-base">check_circle</span>
|
|
|
|
|
|
|
+ <CheckCircle className="h-4 w-4" />
|
|
|
All {cacheAllProgress.total} previews cached successfully!
|
|
All {cacheAllProgress.total} previews cached successfully!
|
|
|
</p>
|
|
</p>
|
|
|
<Button onClick={handleCloseCacheAllDone} className="w-full">
|
|
<Button onClick={handleCloseCacheAllDone} className="w-full">
|
|
@@ -1191,15 +1215,13 @@ export function Layout() {
|
|
|
? 'bg-primary/10'
|
|
? 'bg-primary/10'
|
|
|
: 'bg-amber-500/10'
|
|
: 'bg-amber-500/10'
|
|
|
}`}>
|
|
}`}>
|
|
|
- <span className={`material-icons-outlined text-4xl ${
|
|
|
|
|
- homingJustCompleted
|
|
|
|
|
- ? 'text-green-500'
|
|
|
|
|
- : isHoming
|
|
|
|
|
- ? 'text-primary animate-spin'
|
|
|
|
|
- : 'text-amber-500 animate-pulse'
|
|
|
|
|
- }`}>
|
|
|
|
|
- {homingJustCompleted ? 'check_circle' : 'sync'}
|
|
|
|
|
- </span>
|
|
|
|
|
|
|
+{homingJustCompleted ? (
|
|
|
|
|
+ <CheckCircle className="h-10 w-10 text-green-500" />
|
|
|
|
|
+ ) : isHoming ? (
|
|
|
|
|
+ <Loader2 className="h-10 w-10 text-primary animate-spin" />
|
|
|
|
|
+ ) : (
|
|
|
|
|
+ <Home className="h-10 w-10 text-amber-500 animate-pulse" />
|
|
|
|
|
+ )}
|
|
|
</div>
|
|
</div>
|
|
|
<h2 className="text-2xl font-bold">
|
|
<h2 className="text-2xl font-bold">
|
|
|
{homingJustCompleted
|
|
{homingJustCompleted
|
|
@@ -1244,7 +1266,7 @@ export function Layout() {
|
|
|
<div className="bg-muted/50 rounded-lg border overflow-hidden">
|
|
<div className="bg-muted/50 rounded-lg border overflow-hidden">
|
|
|
<div className="flex items-center justify-between px-4 py-2 border-b bg-muted">
|
|
<div className="flex items-center justify-between px-4 py-2 border-b bg-muted">
|
|
|
<div className="flex items-center gap-2">
|
|
<div className="flex items-center gap-2">
|
|
|
- <span className="material-icons-outlined text-base">terminal</span>
|
|
|
|
|
|
|
+ <Terminal className="h-4 w-4" />
|
|
|
<span className="text-sm font-medium">
|
|
<span className="text-sm font-medium">
|
|
|
{isHoming || homingJustCompleted ? 'Homing Log' : 'Connection Log'}
|
|
{isHoming || homingJustCompleted ? 'Homing Log' : 'Connection Log'}
|
|
|
</span>
|
|
</span>
|
|
@@ -1260,7 +1282,7 @@ export function Layout() {
|
|
|
className="text-xs text-muted-foreground hover:text-foreground flex items-center gap-1 transition-colors"
|
|
className="text-xs text-muted-foreground hover:text-foreground flex items-center gap-1 transition-colors"
|
|
|
title="Copy logs to clipboard"
|
|
title="Copy logs to clipboard"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons text-sm">content_copy</span>
|
|
|
|
|
|
|
+ <Copy className="h-3.5 w-3.5" />
|
|
|
Copy
|
|
Copy
|
|
|
</button>
|
|
</button>
|
|
|
<span className="text-xs text-muted-foreground">
|
|
<span className="text-xs text-muted-foreground">
|
|
@@ -1301,7 +1323,7 @@ export function Layout() {
|
|
|
onClick={() => setKeepHomingLogsOpen(true)}
|
|
onClick={() => setKeepHomingLogsOpen(true)}
|
|
|
className="gap-2"
|
|
className="gap-2"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons text-base">visibility</span>
|
|
|
|
|
|
|
+ <Eye className="h-4 w-4" />
|
|
|
Keep Open
|
|
Keep Open
|
|
|
</Button>
|
|
</Button>
|
|
|
<Button
|
|
<Button
|
|
@@ -1311,7 +1333,7 @@ export function Layout() {
|
|
|
}}
|
|
}}
|
|
|
className="gap-2"
|
|
className="gap-2"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons text-base">close</span>
|
|
|
|
|
|
|
+ <X className="h-4 w-4" />
|
|
|
Dismiss
|
|
Dismiss
|
|
|
</Button>
|
|
</Button>
|
|
|
</>
|
|
</>
|
|
@@ -1323,7 +1345,7 @@ export function Layout() {
|
|
|
}}
|
|
}}
|
|
|
className="gap-2"
|
|
className="gap-2"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons text-base">close</span>
|
|
|
|
|
|
|
+ <X className="h-4 w-4" />
|
|
|
Close Logs
|
|
Close Logs
|
|
|
</Button>
|
|
</Button>
|
|
|
)}
|
|
)}
|
|
@@ -1338,7 +1360,7 @@ export function Layout() {
|
|
|
onClick={() => setHomingDismissed(true)}
|
|
onClick={() => setHomingDismissed(true)}
|
|
|
className="gap-2 text-muted-foreground"
|
|
className="gap-2 text-muted-foreground"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons text-base">visibility_off</span>
|
|
|
|
|
|
|
+ <EyeOff className="h-4 w-4" />
|
|
|
Dismiss
|
|
Dismiss
|
|
|
</Button>
|
|
</Button>
|
|
|
</div>
|
|
</div>
|
|
@@ -1383,9 +1405,7 @@ export function Layout() {
|
|
|
shineColor={isDark ? '#ffffff' : '#999999'}
|
|
shineColor={isDark ? '#ffffff' : '#999999'}
|
|
|
spread={75}
|
|
spread={75}
|
|
|
/>
|
|
/>
|
|
|
- <span className="material-icons-outlined text-muted-foreground text-sm group-hover:text-foreground transition-colors">
|
|
|
|
|
- expand_more
|
|
|
|
|
- </span>
|
|
|
|
|
|
|
+<ChevronDown className="h-3.5 w-3.5 text-muted-foreground group-hover:text-foreground transition-colors" />
|
|
|
<span
|
|
<span
|
|
|
className={`w-2 h-2 rounded-full ${
|
|
className={`w-2 h-2 rounded-full ${
|
|
|
!isBackendConnected
|
|
!isBackendConnected
|
|
@@ -1416,7 +1436,7 @@ export function Layout() {
|
|
|
className="rounded-full"
|
|
className="rounded-full"
|
|
|
aria-label="Open menu"
|
|
aria-label="Open menu"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons-outlined">menu</span>
|
|
|
|
|
|
|
+ <Menu className="h-5 w-5" />
|
|
|
</Button>
|
|
</Button>
|
|
|
</PopoverTrigger>
|
|
</PopoverTrigger>
|
|
|
<PopoverContent align="end" className="w-56 p-2">
|
|
<PopoverContent align="end" className="w-56 p-2">
|
|
@@ -1425,16 +1445,14 @@ export function Layout() {
|
|
|
onClick={() => setIsDark(!isDark)}
|
|
onClick={() => setIsDark(!isDark)}
|
|
|
className="flex items-center gap-3 w-full px-3 py-2 text-sm rounded-md hover:bg-accent transition-colors"
|
|
className="flex items-center gap-3 w-full px-3 py-2 text-sm rounded-md hover:bg-accent transition-colors"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons-outlined text-xl">
|
|
|
|
|
- {isDark ? 'light_mode' : 'dark_mode'}
|
|
|
|
|
- </span>
|
|
|
|
|
|
|
+ {isDark ? <Sun className="h-5 w-5" /> : <Moon className="h-5 w-5" />}
|
|
|
{isDark ? 'Light Mode' : 'Dark Mode'}
|
|
{isDark ? 'Light Mode' : 'Dark Mode'}
|
|
|
</button>
|
|
</button>
|
|
|
<button
|
|
<button
|
|
|
onClick={handleToggleLogs}
|
|
onClick={handleToggleLogs}
|
|
|
className="flex items-center gap-3 w-full px-3 py-2 text-sm rounded-md hover:bg-accent transition-colors"
|
|
className="flex items-center gap-3 w-full px-3 py-2 text-sm rounded-md hover:bg-accent transition-colors"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons-outlined text-xl">article</span>
|
|
|
|
|
|
|
+ <FileText className="h-5 w-5" />
|
|
|
View Logs
|
|
View Logs
|
|
|
</button>
|
|
</button>
|
|
|
<Separator className="my-1" />
|
|
<Separator className="my-1" />
|
|
@@ -1442,14 +1460,14 @@ export function Layout() {
|
|
|
onClick={handleRestart}
|
|
onClick={handleRestart}
|
|
|
className="flex items-center gap-3 w-full px-3 py-2 text-sm rounded-md hover:bg-accent transition-colors text-amber-500"
|
|
className="flex items-center gap-3 w-full px-3 py-2 text-sm rounded-md hover:bg-accent transition-colors text-amber-500"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons-outlined text-xl">restart_alt</span>
|
|
|
|
|
|
|
+ <RotateCcw className="h-5 w-5" />
|
|
|
Restart Docker
|
|
Restart Docker
|
|
|
</button>
|
|
</button>
|
|
|
<button
|
|
<button
|
|
|
onClick={handleShutdown}
|
|
onClick={handleShutdown}
|
|
|
className="flex items-center gap-3 w-full px-3 py-2 text-sm rounded-md hover:bg-accent transition-colors text-red-500"
|
|
className="flex items-center gap-3 w-full px-3 py-2 text-sm rounded-md hover:bg-accent transition-colors text-red-500"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons-outlined text-xl">power_settings_new</span>
|
|
|
|
|
|
|
+ <Power className="h-5 w-5" />
|
|
|
Shutdown
|
|
Shutdown
|
|
|
</button>
|
|
</button>
|
|
|
</div>
|
|
</div>
|
|
@@ -1467,9 +1485,7 @@ export function Layout() {
|
|
|
className="rounded-full"
|
|
className="rounded-full"
|
|
|
aria-label="Open menu"
|
|
aria-label="Open menu"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons-outlined">
|
|
|
|
|
- {isMobileMenuOpen ? 'close' : 'menu'}
|
|
|
|
|
- </span>
|
|
|
|
|
|
|
+{isMobileMenuOpen ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
|
|
|
</Button>
|
|
</Button>
|
|
|
</PopoverTrigger>
|
|
</PopoverTrigger>
|
|
|
<PopoverContent align="end" className="w-56 p-2">
|
|
<PopoverContent align="end" className="w-56 p-2">
|
|
@@ -1481,9 +1497,7 @@ export function Layout() {
|
|
|
}}
|
|
}}
|
|
|
className="flex items-center gap-3 w-full px-3 py-2 text-sm rounded-md hover:bg-accent transition-colors"
|
|
className="flex items-center gap-3 w-full px-3 py-2 text-sm rounded-md hover:bg-accent transition-colors"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons-outlined text-xl">
|
|
|
|
|
- {isDark ? 'light_mode' : 'dark_mode'}
|
|
|
|
|
- </span>
|
|
|
|
|
|
|
+ {isDark ? <Sun className="h-5 w-5" /> : <Moon className="h-5 w-5" />}
|
|
|
{isDark ? 'Light Mode' : 'Dark Mode'}
|
|
{isDark ? 'Light Mode' : 'Dark Mode'}
|
|
|
</button>
|
|
</button>
|
|
|
<button
|
|
<button
|
|
@@ -1493,7 +1507,7 @@ export function Layout() {
|
|
|
}}
|
|
}}
|
|
|
className="flex items-center gap-3 w-full px-3 py-2 text-sm rounded-md hover:bg-accent transition-colors"
|
|
className="flex items-center gap-3 w-full px-3 py-2 text-sm rounded-md hover:bg-accent transition-colors"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons-outlined text-xl">article</span>
|
|
|
|
|
|
|
+ <FileText className="h-5 w-5" />
|
|
|
View Logs
|
|
View Logs
|
|
|
</button>
|
|
</button>
|
|
|
<Separator className="my-1" />
|
|
<Separator className="my-1" />
|
|
@@ -1504,7 +1518,7 @@ export function Layout() {
|
|
|
}}
|
|
}}
|
|
|
className="flex items-center gap-3 w-full px-3 py-2 text-sm rounded-md hover:bg-accent transition-colors text-amber-500"
|
|
className="flex items-center gap-3 w-full px-3 py-2 text-sm rounded-md hover:bg-accent transition-colors text-amber-500"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons-outlined text-xl">restart_alt</span>
|
|
|
|
|
|
|
+ <RotateCcw className="h-5 w-5" />
|
|
|
Restart Docker
|
|
Restart Docker
|
|
|
</button>
|
|
</button>
|
|
|
<button
|
|
<button
|
|
@@ -1514,7 +1528,7 @@ export function Layout() {
|
|
|
}}
|
|
}}
|
|
|
className="flex items-center gap-3 w-full px-3 py-2 text-sm rounded-md hover:bg-accent transition-colors text-red-500"
|
|
className="flex items-center gap-3 w-full px-3 py-2 text-sm rounded-md hover:bg-accent transition-colors text-red-500"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons-outlined text-xl">power_settings_new</span>
|
|
|
|
|
|
|
+ <Power className="h-5 w-5" />
|
|
|
Shutdown
|
|
Shutdown
|
|
|
</button>
|
|
</button>
|
|
|
</div>
|
|
</div>
|
|
@@ -1603,7 +1617,7 @@ export function Layout() {
|
|
|
className="rounded-full"
|
|
className="rounded-full"
|
|
|
title="Copy logs"
|
|
title="Copy logs"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons-outlined text-base">content_copy</span>
|
|
|
|
|
|
|
+ <Copy className="h-4 w-4" />
|
|
|
</Button>
|
|
</Button>
|
|
|
<Button
|
|
<Button
|
|
|
variant="ghost"
|
|
variant="ghost"
|
|
@@ -1612,7 +1626,7 @@ export function Layout() {
|
|
|
className="rounded-full"
|
|
className="rounded-full"
|
|
|
title="Download logs"
|
|
title="Download logs"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons-outlined text-base">download</span>
|
|
|
|
|
|
|
+ <Download className="h-4 w-4" />
|
|
|
</Button>
|
|
</Button>
|
|
|
<Button
|
|
<Button
|
|
|
variant="ghost"
|
|
variant="ghost"
|
|
@@ -1621,7 +1635,7 @@ export function Layout() {
|
|
|
className="rounded-full"
|
|
className="rounded-full"
|
|
|
title="Close"
|
|
title="Close"
|
|
|
>
|
|
>
|
|
|
- <span className="material-icons-outlined text-base">close</span>
|
|
|
|
|
|
|
+ <X className="h-4 w-4" />
|
|
|
</Button>
|
|
</Button>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -1634,7 +1648,7 @@ export function Layout() {
|
|
|
{/* Loading indicator for older logs */}
|
|
{/* Loading indicator for older logs */}
|
|
|
{isLoadingMoreLogs && (
|
|
{isLoadingMoreLogs && (
|
|
|
<div className="flex items-center justify-center gap-2 py-2 text-muted-foreground">
|
|
<div className="flex items-center justify-center gap-2 py-2 text-muted-foreground">
|
|
|
- <span className="material-icons-outlined text-sm animate-spin">sync</span>
|
|
|
|
|
|
|
+ <Loader2 className="h-3.5 w-3.5 animate-spin" />
|
|
|
<span>Loading older logs...</span>
|
|
<span>Loading older logs...</span>
|
|
|
</div>
|
|
</div>
|
|
|
)}
|
|
)}
|
|
@@ -1677,9 +1691,11 @@ export function Layout() {
|
|
|
style={{ bottom: 'calc(4.5rem + env(safe-area-inset-bottom, 0px))' }}
|
|
style={{ bottom: 'calc(4.5rem + env(safe-area-inset-bottom, 0px))' }}
|
|
|
aria-label={isCurrentlyPlaying ? 'Now Playing' : 'Not Playing'}
|
|
aria-label={isCurrentlyPlaying ? 'Now Playing' : 'Not Playing'}
|
|
|
>
|
|
>
|
|
|
- <span className={`material-icons-outlined text-xl ${isCurrentlyPlaying ? 'text-primary' : 'text-muted-foreground'}`}>
|
|
|
|
|
- {isCurrentlyPlaying ? 'play_circle' : 'stop_circle'}
|
|
|
|
|
- </span>
|
|
|
|
|
|
|
+{isCurrentlyPlaying ? (
|
|
|
|
|
+ <PlayCircle className="h-5 w-5 text-primary" />
|
|
|
|
|
+ ) : (
|
|
|
|
|
+ <StopCircle className="h-5 w-5 text-muted-foreground" />
|
|
|
|
|
+ )}
|
|
|
<span className="text-sm font-medium">
|
|
<span className="text-sm font-medium">
|
|
|
{isCurrentlyPlaying ? 'Now Playing' : 'Not Playing'}
|
|
{isCurrentlyPlaying ? 'Now Playing' : 'Not Playing'}
|
|
|
</span>
|
|
</span>
|
|
@@ -1705,9 +1721,7 @@ export function Layout() {
|
|
|
{isActive && (
|
|
{isActive && (
|
|
|
<span className="absolute -top-0.5 w-8 h-1 rounded-full bg-primary" />
|
|
<span className="absolute -top-0.5 w-8 h-1 rounded-full bg-primary" />
|
|
|
)}
|
|
)}
|
|
|
- <span className={`text-xl ${isActive ? 'material-icons' : 'material-icons-outlined'}`}>
|
|
|
|
|
- {item.icon}
|
|
|
|
|
- </span>
|
|
|
|
|
|
|
+ <item.icon className="h-5 w-5" strokeWidth={isActive ? 2.5 : 1.5} />
|
|
|
<span className="text-xs font-medium">{item.label}</span>
|
|
<span className="text-xs font-medium">{item.label}</span>
|
|
|
</Link>
|
|
</Link>
|
|
|
)
|
|
)
|