Преглед изворни кода

- Slicer Protocol:
- Add utils/slicer.ts with OS detection for protocol handler
- Windows: bambustudio://, macOS/Linux: bambustudioopen://
- Update all usages in ArchivesPage.tsx and ModelViewerModal.tsx

maziggy пре 4 месеци
родитељ
комит
01bc211616

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

@@ -4,6 +4,7 @@ import { ModelViewer } from './ModelViewer';
 import { GcodeViewer } from './GcodeViewer';
 import { Button } from './Button';
 import { api } from '../api/client';
+import { openInSlicer } from '../utils/slicer';
 
 type ViewTab = '3d' | 'gcode';
 
@@ -55,11 +56,10 @@ export function ModelViewerModal({ archiveId, title, onClose }: ModelViewerModal
   }, [archiveId]);
 
   const handleOpenInSlicer = () => {
-    // Use bambustudioopen:// protocol like MakerWorld does
     // URL must include .3mf filename for Bambu Studio to recognize the format
     const filename = title || 'model';
     const downloadUrl = `${window.location.origin}${api.getArchiveForSlicer(archiveId, filename)}`;
-    window.location.href = `bambustudioopen://${encodeURIComponent(downloadUrl)}`;
+    openInSlicer(downloadUrl);
   };
 
   return (

+ 7 - 6
frontend/src/pages/ArchivesPage.tsx

@@ -42,6 +42,7 @@ import {
   FolderKanban,
 } from 'lucide-react';
 import { api } from '../api/client';
+import { openInSlicer } from '../utils/slicer';
 import { useIsMobile } from '../hooks/useIsMobile';
 import type { Archive, ProjectListItem } from '../api/client';
 import { Card, CardContent } from '../components/Card';
@@ -233,7 +234,7 @@ function ArchiveCard({
         onClick: () => {
           const filename = archive.print_name || archive.filename || 'model';
           const downloadUrl = `${window.location.origin}${api.getArchiveForSlicer(archive.id, filename)}`;
-          window.location.href = `bambustudioopen://${encodeURIComponent(downloadUrl)}`;
+          openInSlicer(downloadUrl);
         },
       },
     ] : [
@@ -243,7 +244,7 @@ function ArchiveCard({
         onClick: () => {
           const filename = archive.print_name || archive.filename || 'model';
           const downloadUrl = `${window.location.origin}${api.getArchiveForSlicer(archive.id, filename)}`;
-          window.location.href = `bambustudioopen://${encodeURIComponent(downloadUrl)}`;
+          openInSlicer(downloadUrl);
         },
       },
     ]),
@@ -498,7 +499,7 @@ function ArchiveCard({
               // Open source 3MF in Bambu Studio - use filename in URL for slicer compatibility
               const sourceName = (archive.print_name || archive.filename || 'source').replace(/\.gcode\.3mf$/i, '') + '_source';
               const downloadUrl = `${window.location.origin}${api.getSource3mfForSlicer(archive.id, sourceName)}`;
-              window.location.href = `bambustudioopen://${encodeURIComponent(downloadUrl)}`;
+              openInSlicer(downloadUrl);
             }}
             title="Open source 3MF in Bambu Studio (right-click for more options)"
           >
@@ -684,7 +685,7 @@ function ArchiveCard({
                 onClick={() => {
                   const filename = archive.print_name || archive.filename || 'model';
                   const downloadUrl = `${window.location.origin}${api.getArchiveForSlicer(archive.id, filename)}`;
-                  window.location.href = `bambustudioopen://${encodeURIComponent(downloadUrl)}`;
+                  openInSlicer(downloadUrl);
                 }}
                 title="Open in Bambu Studio"
               >
@@ -700,7 +701,7 @@ function ArchiveCard({
               onClick={() => {
                 const filename = archive.print_name || archive.filename || 'model';
                 const downloadUrl = `${window.location.origin}${api.getArchiveForSlicer(archive.id, filename)}`;
-                window.location.href = `bambustudioopen://${encodeURIComponent(downloadUrl)}`;
+                openInSlicer(downloadUrl);
               }}
               title="Open in Bambu Studio to slice"
             >
@@ -1850,7 +1851,7 @@ export function ArchivesPage() {
                     onClick={() => {
                       const filename = archive.print_name || archive.filename || 'model';
                       const downloadUrl = `${window.location.origin}${api.getArchiveForSlicer(archive.id, filename)}`;
-                      window.location.href = `bambustudioopen://${encodeURIComponent(downloadUrl)}`;
+                      openInSlicer(downloadUrl);
                     }}
                     title="Slice"
                   >

+ 70 - 0
frontend/src/utils/slicer.ts

@@ -0,0 +1,70 @@
+/**
+ * Utility for opening files in Bambu Studio slicer
+ *
+ * The URL protocol handler is OS-specific:
+ * - Windows: bambustudio://
+ * - macOS/Linux: bambustudioopen://
+ */
+
+type Platform = 'windows' | 'macos' | 'linux' | 'unknown';
+
+/**
+ * Detect the user's operating system
+ */
+export function detectPlatform(): Platform {
+  const userAgent = navigator.userAgent.toLowerCase();
+  const platform = navigator.platform?.toLowerCase() || '';
+
+  if (userAgent.includes('win') || platform.includes('win')) {
+    return 'windows';
+  }
+  if (userAgent.includes('mac') || platform.includes('mac')) {
+    return 'macos';
+  }
+  if (userAgent.includes('linux') || platform.includes('linux')) {
+    return 'linux';
+  }
+  return 'unknown';
+}
+
+/**
+ * Get the appropriate slicer protocol for the current OS
+ */
+export function getSlicerProtocol(): string {
+  const platform = detectPlatform();
+
+  switch (platform) {
+    case 'windows':
+      return 'bambustudio://';
+    case 'macos':
+    case 'linux':
+    default:
+      return 'bambustudioopen://';
+  }
+}
+
+/**
+ * Open a URL in Bambu Studio slicer
+ * @param downloadUrl - The URL to the file to open (will be encoded)
+ */
+export function openInSlicer(downloadUrl: string): void {
+  const protocol = getSlicerProtocol();
+  window.location.href = `${protocol}${encodeURIComponent(downloadUrl)}`;
+}
+
+/**
+ * Build a full download URL for a file
+ * @param path - The API path (e.g., from api.getArchiveForSlicer())
+ */
+export function buildDownloadUrl(path: string): string {
+  return `${window.location.origin}${path}`;
+}
+
+/**
+ * Convenience function to open an archive in the slicer
+ * @param path - The API path to the archive
+ */
+export function openArchiveInSlicer(path: string): void {
+  const downloadUrl = buildDownloadUrl(path);
+  openInSlicer(downloadUrl);
+}

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
static/assets/index-DNsmdSrp.js


+ 1 - 1
static/index.html

@@ -23,7 +23,7 @@
 
     <!-- Splash screens for iOS -->
     <link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
-    <script type="module" crossorigin src="/assets/index-VFINsn3X.js"></script>
+    <script type="module" crossorigin src="/assets/index-DNsmdSrp.js"></script>
     <link rel="stylesheet" crossorigin href="/assets/index-BmBv9fEm.css">
   </head>
   <body>

Неке датотеке нису приказане због велике количине промена