enhance UI, notif prevent copy paste jadi satu dengan succeas card tempatnya dan image resize
parent
7c1bfdc35a
commit
2c07b8518e
|
|
@ -24,7 +24,8 @@ body {
|
||||||
|
|
||||||
.lesson-content h1, .lesson-content h2, .lesson-content h3 {
|
.lesson-content h1, .lesson-content h2, .lesson-content h3 {
|
||||||
color: #2c3e50;
|
color: #2c3e50;
|
||||||
margin-top: 20px;
|
margin-top: 30px;
|
||||||
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lesson-content h1 {
|
.lesson-content h1 {
|
||||||
|
|
@ -33,8 +34,22 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.lesson-content p {
|
.lesson-content p {
|
||||||
line-height: 1.6;
|
line-height: 1.8;
|
||||||
margin-bottom: 15px;
|
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 {
|
.lesson-content code {
|
||||||
|
|
@ -160,10 +175,46 @@ body {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lesson-content img {
|
.lesson-content img, .home-content img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
height: auto;
|
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 {
|
.lesson-content figure {
|
||||||
|
|
|
||||||
|
|
@ -354,6 +354,38 @@
|
||||||
studentTokenInput.disabled = false;
|
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');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,12 @@
|
||||||
<strong>Tugas anda berhasil!</strong> Output sesuai dengan yang diharapkan.
|
<strong>Tugas anda berhasil!</strong> Output sesuai dengan yang diharapkan.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Warning message card for copy-paste detection -->
|
||||||
|
<div id="warning-message" class="alert alert-danger d-none mt-3" role="alert">
|
||||||
|
<i class="fas fa-exclamation-triangle me-2"></i>
|
||||||
|
<span id="warning-message-text">Peringatan: Copy-paste tidak diperbolehkan. Silakan ketik kode Anda secara manual.</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="output" class="mt-3 p-3 border rounded bg-light d-none" style="max-height: 200px; overflow-y: auto;">
|
<div id="output" class="mt-3 p-3 border rounded bg-light d-none" style="max-height: 200px; overflow-y: auto;">
|
||||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||||
<h5 class="mb-0"><i class="fas fa-terminal"></i> Output</h5>
|
<h5 class="mb-0"><i class="fas fa-terminal"></i> Output</h5>
|
||||||
|
|
@ -379,40 +385,39 @@
|
||||||
showCopyPasteNotification('Cut detected. Cut is not allowed in the code editor. Please type your code manually.');
|
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
|
// Prevent context menu (right-click) on the code editor to avoid paste options
|
||||||
// We'll handle paste operations separately in the paste event
|
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() {
|
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) {
|
function showCopyPasteNotification(message) {
|
||||||
// Create or update notification element
|
const warningElement = document.getElementById('warning-message');
|
||||||
let notificationEl = document.getElementById('copy-paste-notification');
|
const warningTextElement = document.getElementById('warning-message-text');
|
||||||
if (!notificationEl) {
|
|
||||||
notificationEl = document.createElement('div');
|
if (warningElement && warningTextElement) {
|
||||||
notificationEl.id = 'copy-paste-notification';
|
warningTextElement.textContent = message;
|
||||||
notificationEl.style.position = 'fixed';
|
warningElement.classList.remove('d-none');
|
||||||
notificationEl.style.top = '20px';
|
|
||||||
notificationEl.style.right = '20px';
|
// Hide warning after 5 seconds
|
||||||
notificationEl.style.padding = '10px 15px';
|
setTimeout(() => {
|
||||||
notificationEl.style.backgroundColor = '#dc3545';
|
warningElement.classList.add('d-none');
|
||||||
notificationEl.style.color = 'white';
|
}, 5000);
|
||||||
notificationEl.style.borderRadius = '4px';
|
|
||||||
notificationEl.style.zIndex = '10000';
|
|
||||||
notificationEl.style.boxShadow = '0 2px 10px rgba(0,0,0,0.2)';
|
|
||||||
document.body.appendChild(notificationEl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notificationEl.textContent = message;
|
|
||||||
notificationEl.style.display = 'block';
|
|
||||||
|
|
||||||
// Hide notification after 3 seconds
|
|
||||||
setTimeout(() => {
|
|
||||||
notificationEl.style.display = 'none';
|
|
||||||
}, 3000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enhanced mobile clipboard detection algorithm
|
// 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');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue