fix: resolve 401 Unauthorized in Gemini editUVLayer by properly passing auth token, update loading UI with grayscale/blur, fix WebGLShadowMap deprecation warnings
Build and Deploy / build-and-push (push) Successful in 28s
Build and Deploy / build-and-push (push) Successful in 28s
This commit is contained in:
@@ -29,7 +29,7 @@ const ModelPreview = ({ url }: { url: string }) => {
|
||||
if (!model) return <div className="absolute inset-0 flex items-center justify-center"><Loader2 className="w-8 h-8 animate-spin text-zinc-500" /></div>;
|
||||
|
||||
return (
|
||||
<Canvas shadows camera={{ position: [0, 1.5, 3], fov: 45 }}>
|
||||
<Canvas shadows={{ type: THREE.PCFShadowMap }} camera={{ position: [0, 1.5, 3], fov: 45 }}>
|
||||
<Stage environment="studio" intensity={0.5}>
|
||||
<primitive object={model} />
|
||||
</Stage>
|
||||
@@ -39,7 +39,7 @@ const ModelPreview = ({ url }: { url: string }) => {
|
||||
};
|
||||
|
||||
export const ImageTo3DModal: React.FC<ImageTo3DModalProps> = ({ isOpen, onClose, onPushToApp }) => {
|
||||
const { profile, setProfile, token } = useAuthStore();
|
||||
const { profile, setProfile } = useAuthStore();
|
||||
const [meshyApiKey, setMeshyApiKey] = useState('');
|
||||
|
||||
// Image states
|
||||
@@ -97,6 +97,7 @@ export const ImageTo3DModal: React.FC<ImageTo3DModalProps> = ({ isOpen, onClose,
|
||||
setCleanedImagePreview(null);
|
||||
try {
|
||||
const base64 = await fileToDataUrl(fileToClean);
|
||||
const token = localStorage.getItem('auth_token') || '';
|
||||
const newUrl = await editUVLayer("Remove the background and make it solid transparent or white. Also carefully remove all text, labels, logos, and stickers, keeping the product as a perfectly clean, plain, unbranded object.", base64, token);
|
||||
|
||||
const res = await fetch(newUrl);
|
||||
@@ -300,10 +301,13 @@ export const ImageTo3DModal: React.FC<ImageTo3DModalProps> = ({ isOpen, onClose,
|
||||
{/* Cleaned Image */}
|
||||
<div className="flex-1 relative border-2 border-solid border-zinc-700 rounded-xl overflow-hidden bg-zinc-900/50 flex items-center justify-center group">
|
||||
{isCleaningImage ? (
|
||||
<div className="flex flex-col items-center text-zinc-400 gap-3">
|
||||
<Loader2 size={28} className="animate-spin text-blue-500" />
|
||||
<span className="text-sm font-medium">AI Cleaning...</span>
|
||||
</div>
|
||||
<>
|
||||
<img src={originalImagePreview} alt="Original Grayscale" className="absolute inset-0 w-full h-full object-contain p-2 opacity-30 grayscale blur-sm" />
|
||||
<div className="absolute inset-0 flex flex-col items-center justify-center text-zinc-300 gap-3 bg-black/40 z-10">
|
||||
<Loader2 size={28} className="animate-spin text-blue-500" />
|
||||
<span className="text-sm font-medium">AI Cleaning Image...</span>
|
||||
</div>
|
||||
</>
|
||||
) : cleanedImagePreview ? (
|
||||
<>
|
||||
<img src={cleanedImagePreview} alt="Cleaned" className="w-full h-full object-contain p-2" />
|
||||
@@ -405,22 +409,23 @@ export const ImageTo3DModal: React.FC<ImageTo3DModalProps> = ({ isOpen, onClose,
|
||||
<h3 className="text-sm font-bold text-zinc-200">3D Preview</h3>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 relative flex items-center justify-center">
|
||||
{generatedModelUrl ? (
|
||||
<div className="flex-1 relative flex items-center justify-center overflow-hidden">
|
||||
{isGenerating ? (
|
||||
<>
|
||||
{cleanedImagePreview || originalImagePreview ? (
|
||||
<img src={(cleanedImagePreview || originalImagePreview) as string} alt="Generating Base" className="absolute inset-0 w-full h-full object-contain p-8 opacity-20 grayscale blur-md scale-110" />
|
||||
) : null}
|
||||
<div className="absolute inset-0 flex flex-col items-center justify-center text-zinc-300 bg-black/60 z-20">
|
||||
<Loader2 size={36} className="animate-spin text-blue-500 mb-4" />
|
||||
<p className="text-sm font-medium text-zinc-200">{progressMessage}</p>
|
||||
</div>
|
||||
</>
|
||||
) : generatedModelUrl ? (
|
||||
<ModelPreview url={generatedModelUrl} />
|
||||
) : (
|
||||
<div className="flex flex-col items-center justify-center text-zinc-600 p-6 text-center">
|
||||
{isGenerating ? (
|
||||
<>
|
||||
<Loader2 size={32} className="animate-spin text-blue-500 mb-4" />
|
||||
<p className="text-sm font-medium text-zinc-300">{progressMessage}</p>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Box size={32} className="mb-3 opacity-50" />
|
||||
<p className="text-sm">Your 3D model will appear here</p>
|
||||
</>
|
||||
)}
|
||||
<Box size={32} className="mb-3 opacity-50" />
|
||||
<p className="text-sm">Your 3D model will appear here</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -48,7 +48,7 @@ export function UVEditor({ onClose, onSave, targetObject, loadedModel, sceneObje
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const dragRef = useRef<{ handle: Handle; startX: number; startY: number; layer: Layer } | null>(null);
|
||||
|
||||
const token = useAuthStore(state => state.token);
|
||||
const token = localStorage.getItem('auth_token') || '';
|
||||
const [aiPrompt, setAiPrompt] = useState("");
|
||||
const [isEditingLayer, setIsEditingLayer] = useState(false);
|
||||
const [aiPreviewUrl, setAiPreviewUrl] = useState<string | null>(null);
|
||||
@@ -596,7 +596,7 @@ export function UVEditor({ onClose, onSave, targetObject, loadedModel, sceneObje
|
||||
<span className="text-[10px] font-bold text-zinc-500 uppercase tracking-widest">3D Preview</span>
|
||||
</div>
|
||||
<div className="w-full aspect-square bg-zinc-950 rounded-xl overflow-hidden border border-zinc-800">
|
||||
<Canvas shadows camera={{ position: [2, 2, 2], fov: 45 }}>
|
||||
<Canvas shadows={{ type: THREE.PCFShadowMap }} camera={{ position: [2, 2, 2], fov: 45 }}>
|
||||
<ambientLight intensity={0.5} />
|
||||
<directionalLight position={[5, 5, 5]} intensity={1} castShadow />
|
||||
<Environment preset="studio" />
|
||||
|
||||
@@ -2451,7 +2451,7 @@ export default function Editor() {
|
||||
<div className="flex-1 relative bg-zinc-950">
|
||||
<ErrorBoundary>
|
||||
<Canvas
|
||||
shadows
|
||||
shadows={{ type: THREE.PCFShadowMap }}
|
||||
dpr={[1, 2]}
|
||||
gl={{ preserveDrawingBuffer: true, alpha: true }}
|
||||
performance={{ min: 0.5 }}
|
||||
|
||||
@@ -406,7 +406,7 @@ export default function SparkPlug() {
|
||||
) : (
|
||||
<div className="w-full h-[400px] bg-zinc-900 rounded-xl overflow-hidden relative border border-zinc-800 flex flex-col items-center justify-center">
|
||||
{generatedGlbUrl ? (
|
||||
<Canvas shadows dpr={[1, 2]} camera={{ position: [0, 0, 4], fov: 45 }}>
|
||||
<Canvas shadows={{ type: THREE.PCFShadowMap }} dpr={[1, 2]} camera={{ position: [0, 0, 4], fov: 45 }}>
|
||||
<Suspense fallback={null}>
|
||||
<Stage environment="studio" intensity={0.5}>
|
||||
<ModelPreview url={generatedGlbUrl} />
|
||||
|
||||
Reference in New Issue
Block a user