Bladeren bron

fix: respect disabled update check setting (#367)

Backend /updates/check endpoint now returns early without calling
GitHub API when check_updates is disabled. Settings page no longer
auto-fetches update status when the setting is off. Printer card
firmware badge falls back to showing the current version from MQTT
instead of disappearing when firmware update checks are disabled.
maziggy 3 maanden geleden
bovenliggende
commit
259c7eaa43

+ 1 - 0
CHANGELOG.md

@@ -16,6 +16,7 @@ All notable changes to Bambuddy will be documented in this file.
 - **K-Profiles View — Accurate Filament Name Resolution** — K-profile filament names are now resolved from builtin filament tables and user cloud presets (via new `/cloud/filament-id-map` endpoint) instead of showing raw IDs like "GFU99" or "P4d64437". Falls back to extracting names from the profile name field.
 
 ### Fixed
+- **Update Check Runs When Disabled** ([#367](https://github.com/maziggy/bambuddy/issues/367)) — The Settings page triggered an update check on every visit even when "Check for updates" was disabled, causing error popups on air-gapped systems with no internet. The backend `/updates/check` endpoint also ignored the setting entirely. Now the backend returns early without making GitHub API calls when the setting is disabled, the Settings page respects the `check_updates` flag before auto-fetching, and the printer card firmware badge shows a neutral version-only display instead of disappearing when firmware update checks are off.
 - **Stale Inventory Assignments Persist After Switching to Spoolman Mode** — When switching from built-in inventory to Spoolman mode, existing spool-to-AMS-slot assignments were not cleaned up. The printer card hover cards continued showing "Assign Spool" buttons that opened the internal inventory modal, and any prior assignments remained visible. Now bulk-deletes all `SpoolAssignment` records when enabling Spoolman, invalidates the frontend cache so printer cards update immediately, and hides the inventory assign/unassign UI on printer cards while in Spoolman mode.
 - **Bulk Archive Delete Leaves Orphaned Database Records** — When bulk-deleting archives, the files were removed from disk before the database commit. If concurrent SQLite writes caused a lock timeout, the commit failed and rolled back — leaving database records pointing to deleted files (broken thumbnails, 404 errors). Fixed by deleting the database record first and only removing files after a successful commit.
 - **Model-Specific Maintenance Tasks for Carbon Rods vs Linear Rails** ([#351](https://github.com/maziggy/bambuddy/issues/351)) — Maintenance tasks "Clean Carbon Rods" and "Lubricate Linear Rails" were shown for all printers regardless of motion system. H2 and A1 series use linear rails (not carbon rods), and X1/P1/P2S series use carbon rods (not linear rails). Maintenance types are now classified by rod/rail type: "Lubricate Carbon Rods" and "Clean Carbon Rods" for X1/P1/P2S, "Lubricate Linear Rails" and "Clean Linear Rails" for A1/H2. Stale and duplicate system types are automatically cleaned up on startup. Includes model-specific wiki links and i18n keys for all 4 locales.

+ 13 - 0
backend/app/api/routes/updates.py

@@ -9,12 +9,14 @@ import sys
 
 import httpx
 from fastapi import APIRouter, BackgroundTasks, Depends
+from sqlalchemy import select
 from sqlalchemy.ext.asyncio import AsyncSession
 
 from backend.app.core.auth import RequirePermissionIfAuthEnabled
 from backend.app.core.config import APP_VERSION, GITHUB_REPO, settings
 from backend.app.core.database import get_db
 from backend.app.core.permissions import Permission
+from backend.app.models.settings import Settings
 from backend.app.models.user import User
 
 logger = logging.getLogger(__name__)
@@ -176,6 +178,17 @@ async def check_for_updates(
     """Check GitHub for available updates."""
     global _update_status
 
+    # Respect the check_updates setting
+    result = await db.execute(select(Settings).where(Settings.key == "check_updates"))
+    setting = result.scalar_one_or_none()
+    if setting and setting.value.lower() == "false":
+        return {
+            "update_available": False,
+            "current_version": APP_VERSION,
+            "latest_version": None,
+            "message": "Update checks are disabled",
+        }
+
     _update_status = {
         "status": "checking",
         "progress": 0,

+ 1 - 0
frontend/src/api/client.ts

@@ -249,6 +249,7 @@ export interface PrinterStatus {
   big_fan1_speed: number | null;     // Auxiliary fan
   big_fan2_speed: number | null;     // Chamber/exhaust fan
   heatbreak_fan_speed: number | null; // Hotend heatbreak fan
+  firmware_version: string | null;   // Firmware version from MQTT
 }
 
 export interface PrinterCreate {

+ 6 - 2
frontend/src/pages/PrintersPage.tsx

@@ -2283,7 +2283,7 @@ function PrinterCard({
                 </button>
               )}
               {/* Firmware Version Badge */}
-              {firmwareInfo?.current_version && firmwareInfo?.latest_version && (
+              {checkPrinterFirmware && firmwareInfo?.current_version && firmwareInfo?.latest_version ? (
                 <button
                   onClick={() => setShowFirmwareModal(true)}
                   className={`flex items-center gap-1 px-2 py-1 rounded-full text-xs hover:opacity-80 transition-opacity ${
@@ -2300,7 +2300,11 @@ function PrinterCard({
                   {firmwareInfo.update_available ? <Download className="w-3 h-3" /> : <CheckCircle className="w-3 h-3" />}
                   {firmwareInfo.current_version}
                 </button>
-              )}
+              ) : status?.firmware_version ? (
+                <span className="flex items-center gap-1 px-2 py-1 rounded-full text-xs bg-bambu-dark-tertiary/50 text-bambu-gray">
+                  {status.firmware_version}
+                </span>
+              ) : null}
             </div>
           )}
         </div>

+ 1 - 0
frontend/src/pages/SettingsPage.tsx

@@ -285,6 +285,7 @@ export function SettingsPage() {
   const { data: updateCheck, refetch: refetchUpdateCheck, isRefetching: isCheckingUpdate } = useQuery({
     queryKey: ['updateCheck'],
     queryFn: api.checkForUpdates,
+    enabled: settings?.check_updates !== false,
     staleTime: 5 * 60 * 1000,
   });
 

File diff suppressed because it is too large
+ 0 - 0
static/assets/index-C9JxyacH.js


File diff suppressed because it is too large
+ 0 - 0
static/assets/index-OqmBOPoC.css


+ 2 - 2
static/index.html

@@ -23,8 +23,8 @@
 
     <!-- Splash screens for iOS -->
     <link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
-    <script type="module" crossorigin src="/assets/index-CwWjVtap.js"></script>
-    <link rel="stylesheet" crossorigin href="/assets/index-C0Wzgyzo.css">
+    <script type="module" crossorigin src="/assets/index-C9JxyacH.js"></script>
+    <link rel="stylesheet" crossorigin href="/assets/index-OqmBOPoC.css">
   </head>
   <body>
     <div id="root"></div>

Some files were not shown because too many files changed in this diff