Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 81 additions & 20 deletions snippets/jupiter-plugin-integrated.jsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,90 @@
import React, { useState, useEffect, useRef } from 'react';

// Jupiter global nesnesinin tipini tanımlamak (TypeScript olmasa da okunabilirlik için)
const JUPITER_PLUGIN_ID = "jupiter-plugin-integrated";
// @ts-ignore
const Jupiter = window.Jupiter;

// Harici betiğin varlığını Promise tabanlı ve temizlenebilir şekilde kontrol eden yardımcı fonksiyon
const waitForJupiter = (timeout = 5000) => {
return new Promise((resolve, reject) => {
let attempts = 0;
const maxAttempts = timeout / 100;

const check = () => {
// @ts-ignore
if (window.Jupiter && window.Jupiter.init) {
return resolve(window.Jupiter);
}

if (attempts >= maxAttempts) {
return reject(new Error("Jupiter script load timeout."));
}

attempts++;
setTimeout(check, 100);
};

check();
});
};


export const JupiterPluginIntegrated = () => {
const [isLoaded, setIsLoaded] = useState(false);
const [error, setError] = useState(null);
// useRef, init işleminin sadece bir kez yapıldığından emin olmak için kullanılır.
const isInitialized = useRef(false);

useEffect(() => {
// Wait for the Jupiter script to load
const checkJupiter = () => {
if (window.Jupiter) {
try {
window.Jupiter.init({
displayMode: "integrated",
integratedTargetId: "jupiter-plugin-integrated",
});
setIsLoaded(true);
} catch (err) {
setError('Failed to initialize Jupiter Plugin');
console.error('Jupiter Plugin initialization error:', err);
// Bileşenin temizlenme (cleanup) fonksiyonunu tutmak için
let timeoutId;
let componentMounted = true;

const initializePlugin = async () => {
try {
// 1. Better Polling / Waiting: Use a Promise-based wait for better structure and cleanup
await waitForJupiter();

// Sadece bir kez başlatıldığından emin ol
if (componentMounted && !isInitialized.current && Jupiter) {

// 2. Initialization: Initialize the widget
Jupiter.init({
displayMode: "integrated",
integratedTargetId: JUPITER_PLUGIN_ID,
});

isInitialized.current = true;
setIsLoaded(true);
}
} catch (err) {
if (componentMounted) {
setError('Failed to initialize Jupiter Plugin.');
console.error('Jupiter Plugin initialization error:', err);
}
} else {
// If Jupiter is not available yet, try again in 100ms
setTimeout(checkJupiter, 100);
}
};

initializePlugin();

// 3. CLEANUP: useEffect içindeki tüm yan etkileri temizle.
return () => {
componentMounted = false;
if (timeoutId) {
clearTimeout(timeoutId);
}

// Harici kütüphanenin destroy metodu varsa çağrılmalıdır.
// Jupiter'in destroy metodu belgelenmemişse bu kısmı atlayın.
if (isInitialized.current && Jupiter && Jupiter.destroy) {
Jupiter.destroy();
isInitialized.current = false;
}
};
}, []); // Bileşen ömrü boyunca sadece bir kez çalışır

// Start checking for Jupiter availability
checkJupiter();
}, []);
// --- Render Logic ---

if (error) {
return (
Expand All @@ -48,9 +108,10 @@ export const JupiterPluginIntegrated = () => {
</div>
)}
<div
id="jupiter-plugin-integrated"
id={JUPITER_PLUGIN_ID}
// isLoaded durumuna göre görünürlük ayarlanır
className={`transition-opacity duration-500 ${isLoaded ? 'opacity-100' : 'opacity-0'}`}
/>
</div>
);
};
};