ソースを参照

Fix patterns not loading due to stale localStorage URL initialization

CRITICAL FIX: Reverted apiClient localStorage pre-initialization that
could cause all API calls to silently fail if users had stale table
data pointing to unreachable servers.

Also includes:
- Increase main content top padding (pt-16 → pt-[4.5rem]) to prevent
  header overlap on mobile
- Make Add Pattern and Cache buttons responsive (h-9 on mobile)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
tuanchris 2 週間 前
コミット
d2d34d0070

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

@@ -1321,7 +1321,7 @@ export function Layout() {
 
       {/* Main Content */}
       <main
-        className={`container mx-auto px-4 pt-16 transition-all duration-300 ${
+        className={`container mx-auto px-4 pt-[4.5rem] transition-all duration-300 ${
           !isLogsOpen && !isNowPlayingOpen ? 'pb-20' :
           !isLogsOpen && isNowPlayingOpen ? 'pb-80' : ''
         }`}

+ 4 - 33
frontend/src/lib/apiClient.ts

@@ -196,40 +196,11 @@ class ApiClient {
   }
 }
 
-/**
- * Initialize base URL from localStorage synchronously.
- * This must happen BEFORE any components mount and try to connect to WebSockets.
- * Otherwise, there's a race condition where components connect to the wrong backend.
- */
-function getInitialBaseUrl(): string {
-  try {
-    const STORAGE_KEY = 'duneweaver_tables'
-    const ACTIVE_TABLE_KEY = 'duneweaver_active_table'
-
-    const stored = localStorage.getItem(STORAGE_KEY)
-    const activeId = localStorage.getItem(ACTIVE_TABLE_KEY)
-
-    if (stored && activeId) {
-      const data = JSON.parse(stored)
-      const activeTable = data.tables?.find((t: { id: string }) => t.id === activeId)
-
-      if (activeTable) {
-        // Only use non-empty URL for remote tables (not the current server)
-        if (!activeTable.isCurrent && activeTable.url && activeTable.url !== window.location.origin) {
-          return activeTable.url.replace(/\/$/, '')
-        }
-      }
-    }
-  } catch (e) {
-    console.warn('Failed to restore base URL from localStorage:', e)
-  }
-
-  return ''
-}
-
-// Export singleton instance with correct initial base URL
+// Export singleton instance
+// Note: Base URL is managed by TableContext after it validates table connectivity.
+// We intentionally don't pre-initialize from localStorage here to avoid pointing
+// to stale/unreachable servers which would cause silent API failures.
 export const apiClient = new ApiClient()
-apiClient.setBaseUrl(getInitialBaseUrl())
 
 // Export class for testing
 export { ApiClient }

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

@@ -835,7 +835,7 @@ export function BrowsePage() {
           variant="ghost"
           onClick={() => fileInputRef.current?.click()}
           disabled={isUploading}
-          className="gap-2 shrink-0 h-11 rounded-full px-4 bg-card border border-border shadow-sm hover:bg-accent"
+          className="gap-2 shrink-0 h-9 w-9 sm:h-11 sm:w-auto rounded-full px-0 sm:px-4 justify-center bg-card border border-border shadow-sm hover:bg-accent"
         >
           {isUploading ? (
             <span className="material-icons-outlined animate-spin text-lg">sync</span>
@@ -918,7 +918,7 @@ export function BrowsePage() {
             <Button
               variant="outline"
               onClick={handleCacheAllPreviews}
-              className="shrink-0 h-11 rounded-full lg:rounded-full bg-card shadow-sm px-3 sm:px-4 gap-2"
+              className="shrink-0 h-9 w-9 sm:h-11 sm:w-auto rounded-full bg-card shadow-sm px-0 sm:px-4 justify-center sm:justify-start gap-2"
               title="Cache All Previews"
             >
               {isCaching ? (