diff --git a/static/style.css b/static/style.css index 9f67320..6ded92b 100644 --- a/static/style.css +++ b/static/style.css @@ -24,7 +24,8 @@ body { .lesson-content h1, .lesson-content h2, .lesson-content h3 { color: #2c3e50; - margin-top: 20px; + margin-top: 30px; + margin-bottom: 20px; } .lesson-content h1 { @@ -33,8 +34,22 @@ body { } .lesson-content p { - line-height: 1.6; - margin-bottom: 15px; + line-height: 1.8; + margin-bottom: 20px; +} + +/* Add spacing after other block elements */ +.lesson-content ul, .lesson-content ol { + margin-top: 15px; + margin-bottom: 20px; +} + +.lesson-content blockquote { + margin-top: 20px; + margin-bottom: 20px; + padding: 15px 20px; + border-left: 4px solid #3498db; + background-color: #f8f9fa; } .lesson-content code { @@ -160,10 +175,46 @@ body { padding: 10px; } -.lesson-content img { +.lesson-content img, .home-content img { max-width: 100%; height: auto; - margin: 10px 0; + margin: 15px 0; + display: block; + cursor: pointer; + transition: transform 0.3s ease; + object-fit: contain; /* Ensures the entire image is visible within its bounds */ +} + +.lesson-content img.zoomable-img { + max-width: 100%; + height: auto; + margin: 15px 0; + display: block; + cursor: zoom-in; + transition: transform 0.3s ease; + object-fit: contain; /* Ensures the entire image is visible within its bounds */ +} + +.lesson-content img.zoomable-img.enlarged { + cursor: zoom-out; + max-width: 95vw; + max-height: 90vh; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + z-index: 1050; /* High z-index to appear above other elements */ + box-shadow: 0 4px 12px rgba(0,0,0,0.3); +} + +.lesson-content img.zoomable-img { + max-width: 100%; + height: auto; + margin: 15px 0; + display: block; + cursor: zoom-in; + transition: transform 0.3s ease; + object-fit: contain; /* Ensures the entire image is visible within its bounds */ } .lesson-content figure { diff --git a/templates/index.html b/templates/index.html index d869807..2768926 100644 --- a/templates/index.html +++ b/templates/index.html @@ -354,6 +354,38 @@ studentTokenInput.disabled = false; }); } + + // Image zoom functionality for home page + document.addEventListener('DOMContentLoaded', function() { + // Select all images inside home content + const homeImages = document.querySelectorAll('.home-content img'); + + homeImages.forEach(img => { + // Add zoomable-img class to make them zoomable + if (!img.classList.contains('zoomable-img')) { + img.classList.add('zoomable-img'); + } + + img.addEventListener('click', function() { + // Toggle enlarged class to zoom in/out + this.classList.toggle('enlarged'); + + // Prevent default behavior to avoid any conflicts + if (event) { + event.preventDefault(); + event.stopPropagation(); + } + }); + }); + + // Add event listener to close enlarged images when clicking outside + document.addEventListener('click', function(event) { + const enlargedImg = document.querySelector('.home-content img.enlarged'); + if (enlargedImg && !event.target.classList.contains('zoomable-img')) { + enlargedImg.classList.remove('enlarged'); + } + }); + }); }); diff --git a/templates/lesson.html b/templates/lesson.html index d3efec0..cc55166 100644 --- a/templates/lesson.html +++ b/templates/lesson.html @@ -110,6 +110,12 @@ Tugas anda berhasil! Output sesuai dengan yang diharapkan. + + +
Output
@@ -379,40 +385,39 @@ showCopyPasteNotification('Cut detected. Cut is not allowed in the code editor. Please type your code manually.'); }; - // Allow context menu (right-click) but prevent paste actions - // We'll handle paste operations separately in the paste event + // Prevent context menu (right-click) on the code editor to avoid paste options + codeEditor.addEventListener('contextmenu', function(e) { + e.preventDefault(); + e.stopPropagation(); + return false; + }); - // Device detection function + // Device detection function - updated to consider screen size as well function isMobileDevice() { - return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); + // Check both user agent and screen size to determine if it's a mobile device + const isUserAgentMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); + + // Also check screen dimensions - if screen width is small, likely mobile device + const isScreenSmall = window.innerWidth <= 768 || window.screen.width <= 768; + + // Return true if either condition is met + return isUserAgentMobile || isScreenSmall; } - // Function to show a temporary notification about copy-paste detection + // Function to show a temporary warning card about copy-paste detection function showCopyPasteNotification(message) { - // Create or update notification element - let notificationEl = document.getElementById('copy-paste-notification'); - if (!notificationEl) { - notificationEl = document.createElement('div'); - notificationEl.id = 'copy-paste-notification'; - notificationEl.style.position = 'fixed'; - notificationEl.style.top = '20px'; - notificationEl.style.right = '20px'; - notificationEl.style.padding = '10px 15px'; - notificationEl.style.backgroundColor = '#dc3545'; - notificationEl.style.color = 'white'; - notificationEl.style.borderRadius = '4px'; - notificationEl.style.zIndex = '10000'; - notificationEl.style.boxShadow = '0 2px 10px rgba(0,0,0,0.2)'; - document.body.appendChild(notificationEl); + const warningElement = document.getElementById('warning-message'); + const warningTextElement = document.getElementById('warning-message-text'); + + if (warningElement && warningTextElement) { + warningTextElement.textContent = message; + warningElement.classList.remove('d-none'); + + // Hide warning after 5 seconds + setTimeout(() => { + warningElement.classList.add('d-none'); + }, 5000); } - - notificationEl.textContent = message; - notificationEl.style.display = 'block'; - - // Hide notification after 3 seconds - setTimeout(() => { - notificationEl.style.display = 'none'; - }, 3000); } // Enhanced mobile clipboard detection algorithm @@ -991,6 +996,33 @@ } }); } + + // Image zoom functionality + document.addEventListener('DOMContentLoaded', function() { + // Select all images inside lesson content + const lessonImages = document.querySelectorAll('.lesson-content img'); + + lessonImages.forEach(img => { + // Add zoomable-img class to make them zoomable + img.classList.add('zoomable-img'); + + img.addEventListener('click', function() { + // Toggle enlarged class to zoom in/out + this.classList.toggle('enlarged'); + + // Prevent default behavior to avoid any conflicts + event.preventDefault(); + }); + }); + + // Add event listener to close enlarged images when clicking outside + document.addEventListener('click', function(event) { + const enlargedImg = document.querySelector('.lesson-content img.enlarged'); + if (enlargedImg && !event.target.classList.contains('zoomable-img')) { + enlargedImg.classList.remove('enlarged'); + } + }); + }); });