diff --git a/public/css/styles.css b/public/css/styles.css index 3f30829..fa6fcde 100644 --- a/public/css/styles.css +++ b/public/css/styles.css @@ -272,5 +272,4 @@ .bg-gray-800.p-6.rounded-lg.shadow-lg p { @apply max-w-full; -} - +} \ No newline at end of file diff --git a/public/index.html b/public/index.html index 1eedb30..e1d96a4 100644 --- a/public/index.html +++ b/public/index.html @@ -447,114 +447,6 @@ - @@ -572,6 +464,8 @@ + + \ No newline at end of file diff --git a/public/js/tutorial.js b/public/js/tutorial.js new file mode 100644 index 0000000..a22fbd6 --- /dev/null +++ b/public/js/tutorial.js @@ -0,0 +1,105 @@ + // Debounce function to prevent multiple triggers on mobile + function debounce(func, wait) { + let timeout; + return function executedFunction(...args) { + const later = () => { + clearTimeout(timeout); + func(...args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; + } + + // Function to update tutorial spans when key display spans are populated + function updateTutorialSpans() { + const holesailHash = document.getElementById('holesailHash').textContent; + const geyserHash = document.getElementById('geyserHash').textContent; + const sftpHash = document.getElementById('sftpHash').textContent; + + document.getElementById('tutorialHolesailHash').textContent = holesailHash; + document.getElementById('tutorialGeyserHash').textContent = geyserHash; + document.getElementById('tutorialSftpHash').textContent = sftpHash; + document.getElementById('tutorialHolesailHashOutput').textContent = holesailHash; + document.getElementById('tutorialHolesailHashOutput2').textContent = holesailHash; + document.getElementById('tutorialHolesailHashHost').textContent = holesailHash; + } + + // Run initially + updateTutorialSpans(); + + // Observe changes to key display spans + const observer = new MutationObserver(updateTutorialSpans); + document.querySelectorAll('#holesailHash, #geyserHash, #sftpHash').forEach(span => { + observer.observe(span, { childList: true, characterData: true, subtree: true }); + }); + + // Ensure notification is hidden on page load + document.addEventListener('DOMContentLoaded', () => { + const notification = document.getElementById('copyNotification'); + + // Add event listeners to copy buttons + document.querySelectorAll('.copy-key-btn').forEach(button => { + button.addEventListener('click', debounce((event) => { + event.preventDefault(); // Prevent default touch behavior + if (!event.isTrusted) return; // Ensure user-initiated action + + const keyElementId = button.getAttribute('data-key-id'); + const keyText = document.getElementById(keyElementId).textContent; + const keyType = button.getAttribute('data-key-type'); + + if (navigator.clipboard && navigator.clipboard.writeText) { + navigator.clipboard.writeText(keyText).then(() => { + // Use showNotification from app.js + window.showNotification(`${keyType} key copied to clipboard!`, 'success', `copy-${keyElementId}`); + }).catch(err => { + console.error(`Failed to copy ${keyType} key: `, err); + window.showNotification(`Failed to copy ${keyType} key.`, 'error', `copy-${keyElementId}`); + }); + } else { + window.showNotification('Clipboard API not supported. Please copy manually.', 'error', `copy-${keyElementId}`); + } + }, 300)); + }); + }); + + // Toggle tutorial section visibility + document.getElementById('toggleTutorial').addEventListener('click', () => { + const tutorialSection = document.getElementById('tutorialSection'); + tutorialSection.classList.toggle('hidden'); + }); + + // Copy summarized tutorial in Markdown with debounced event listener + document.getElementById('copyTutorial').addEventListener('click', debounce((event) => { + event.preventDefault(); // Prevent default touch behavior + if (!event.isTrusted) return; // Ensure user-initiated action + + const holesailHash = document.getElementById('holesailHash').textContent; + const markdownTutorial = `# Join My Minecraft Server with Holesail! + + Holesail is a secure, peer-to-peer tool that lets you connect to my server without public IPs. + + 1. **Install Node.js**: Download and install from [nodejs.org](https://nodejs.org/). + 2. **Install Holesail**: Open a terminal and run: + \`\`\`bash + npm i holesail@2.1.0 + \`\`\` + 3. **Connect to the server**: Use this command with the key: + \`\`\`bash + holesail ${holesailHash} + \`\`\` + 4. **Join in Minecraft**: Once Holesail confirms the connection, connect to \`127.0.0.1:25565\` in Minecraft. + + **Note**: Keep the key private, like an SSH key. No public IPs needed—it's all peer-to-peer!`; + + if (navigator.clipboard && navigator.clipboard.writeText) { + navigator.clipboard.writeText(markdownTutorial).then(() => { + window.showNotification('Tutorial copied to clipboard!', 'success', 'copy-tutorial'); + }).catch(err => { + console.error('Failed to copy tutorial: ', err); + window.showNotification('Failed to copy tutorial. Please copy manually.', 'error', 'copy-tutorial'); + }); + } else { + window.showNotification('Clipboard API not supported. Please copy manually.', 'error', 'copy-tutorial'); + } + }, 300)); // 300ms debounce \ No newline at end of file