mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-17 19:36:28 +02:00
- 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
This commit is contained in:
@@ -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 (
|
||||
|
||||
@@ -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"
|
||||
>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user