Compare commits

...

3 commits

Author SHA1 Message Date
fd88979c32 added function to Fumble when you refresh. Great for keyboard shortcuts
like vim motions or just tapping F2.
2025-01-20 00:46:14 -06:00
49637981b3 added quick and dirty landing page.
TODO;
- Add more about the project and wiby.me
- Add contact me.
- Maybe do irc feature.
2025-01-20 00:06:14 -06:00
f94abea6e9 added shake to Fumble. Works on Android, Doesn't work on iOS yet. 2025-01-19 23:45:18 -06:00
3 changed files with 345 additions and 3 deletions

View file

@ -58,17 +58,75 @@
</div>
</div>
<div id="warningModal" class="modal warning-modal">
<div class="modal-content">
<span class="close-button" style="display: none;">&times;</span>
<h2>⚠️ Slow Down!</h2>
<p>Clicking too quickly may get you flagged as spam by Wiby.me.</p>
<p>Please wait a moment between fumbles.</p>
<div id="cooldownTimer" class="cooldown-timer">
You can close this warning in: <span id="cooldownSeconds">5</span>s
</div>
<button id="warningCloseBtn" class="warning-close-btn" disabled>I Understand</button>
</div>
</div>
<main>
<iframe
id="contentFrame"
src="about:blank"
src="landing.html"
title="Content"
sandbox="allow-scripts allow-same-origin allow-forms allow-popups"
></iframe>
</main>
<script>
if (performance.navigation.type === performance.navigation.TYPE_RELOAD) {
if (sessionStorage.getItem('hasVisited')) {
window.stop();
requestAnimationFrame(() => fumble());
}
} else if (!sessionStorage.getItem('hasVisited')) {
sessionStorage.setItem('hasVisited', 'true');
}
let lastFumbleTime = 0;
const cooldownPeriod = 5000; // 5 seconds cooldown
let cooldownTimer = null;
const fumble = () => {
const currentTime = Date.now();
const timeSinceLastFumble = currentTime - lastFumbleTime;
if (timeSinceLastFumble < cooldownPeriod) {
// Show warning modal
const warningModal = document.getElementById('warningModal');
const cooldownSeconds = document.getElementById('cooldownSeconds');
const closeBtn = document.getElementById('warningCloseBtn');
warningModal.classList.add('show');
closeBtn.disabled = true;
// Update countdown timer
let remainingTime = 5; // 5 second countdown for closing
cooldownSeconds.textContent = remainingTime;
if (cooldownTimer) clearInterval(cooldownTimer);
cooldownTimer = setInterval(() => {
remainingTime--;
if (remainingTime <= 0) {
cooldownSeconds.textContent = '0';
closeBtn.disabled = false;
clearInterval(cooldownTimer);
} else {
cooldownSeconds.textContent = remainingTime;
}
}, 1000);
return;
}
lastFumbleTime = currentTime;
const frame = document.getElementById('contentFrame');
frame.src = 'https://wiby.me/surprise/';
@ -146,12 +204,99 @@
modal.classList.remove('show');
});
// Close modal when clicking outside
// Update warning modal close handler
const warningModal = document.getElementById('warningModal');
const warningCloseBtn = document.getElementById('warningCloseBtn');
warningCloseBtn.addEventListener('click', () => {
if (!warningCloseBtn.disabled) {
warningModal.classList.remove('show');
if (cooldownTimer) clearInterval(cooldownTimer);
}
});
// Remove the click-outside-to-close functionality for warning modal
window.addEventListener('click', (event) => {
if (event.target === modal) {
if (event.target === modal) { // Only for help modal
modal.classList.remove('show');
}
});
// Add shake detection
let lastX = 0;
let lastY = 0;
let lastZ = 0;
let lastUpdate = 0;
const shakeThreshold = 15; // Adjust sensitivity
const shakeTimeout = 1000; // Prevent multiple shakes
let lastShake = 0;
function handleMotion(event) {
const current = event.accelerationIncludingGravity;
const currentTime = new Date().getTime();
const timeDiff = currentTime - lastUpdate;
if (timeDiff > 100) {
const deltaX = Math.abs(current.x - lastX);
const deltaY = Math.abs(current.y - lastY);
const deltaZ = Math.abs(current.z - lastZ);
if (((deltaX > shakeThreshold && deltaY > shakeThreshold) ||
(deltaX > shakeThreshold && deltaZ > shakeThreshold) ||
(deltaY > shakeThreshold && deltaZ > shakeThreshold)) &&
(currentTime - lastShake > shakeTimeout)) {
// Vibrate if available
if ('vibrate' in navigator) {
navigator.vibrate(200);
}
fumble();
lastShake = currentTime;
}
lastX = current.x;
lastY = current.y;
lastZ = current.z;
lastUpdate = currentTime;
}
}
// Request permission and start shake detection on mobile
function initShakeDetection() {
if (typeof DeviceMotionEvent.requestPermission === 'function') {
// iOS 13+ requires permission
DeviceMotionEvent.requestPermission()
.then(permissionState => {
if (permissionState === 'granted') {
window.addEventListener('devicemotion', handleMotion);
}
})
.catch(console.error);
} else {
// Non iOS 13+ devices
window.addEventListener('devicemotion', handleMotion);
}
}
// Initialize shake detection when page loads
if ('DeviceMotionEvent' in window) {
// Add a button to request permission on iOS
if (typeof DeviceMotionEvent.requestPermission === 'function') {
const modal = document.getElementById('helpModal');
const modalContent = modal.querySelector('.modal-content');
const permissionButton = document.createElement('button');
permissionButton.textContent = 'Enable Shake to Fumble';
permissionButton.className = 'permission-button';
permissionButton.addEventListener('click', initShakeDetection);
modalContent.appendChild(permissionButton);
} else {
// Automatically start for non-iOS devices
initShakeDetection();
}
}
</script>
</body>
</html>

101
landing.html Normal file
View file

@ -0,0 +1,101 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Welcome to FumbleAround</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
margin: 0;
padding: 20px;
text-align: center;
background: linear-gradient(135deg, #ff4500 0%, #ff6b4a 100%);
color: white;
}
.container {
max-width: 600px;
padding: 40px;
background: rgba(255, 255, 255, 0.1);
border-radius: 20px;
backdrop-filter: blur(10px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
}
h1 {
font-size: 2.5em;
margin-bottom: 20px;
}
.logo {
width: 120px;
height: 120px;
margin-bottom: 30px;
}
p {
font-size: 1.2em;
line-height: 1.6;
margin-bottom: 20px;
}
.instructions {
font-size: 1.1em;
background: rgba(255, 255, 255, 0.2);
padding: 20px;
border-radius: 10px;
margin-top: 30px;
}
.shake-icon {
font-size: 2em;
margin: 10px 0;
}
@media (max-width: 768px) {
body {
padding: 15px;
}
.container {
padding: 20px;
}
h1 {
font-size: 2em;
}
.logo {
width: 100px;
height: 100px;
}
p {
font-size: 1em;
}
}
</style>
</head>
<body>
<div class="container">
<img src="./Assets/smily.png" alt="FumbleAround Logo" class="logo">
<h1>Welcome to FumbleAround!</h1>
<p>Ready to explore the hidden gems of the internet? FumbleAround helps you discover interesting websites you might never find otherwise.</p>
<p>Click the "Fumble!" button or use the shake gesture on mobile to start your journey.</p>
<div class="instructions">
<p>💡 <strong>Pro Tips:</strong></p>
<p>🌙 Toggle dark mode for comfortable browsing</p>
<p>📱 On mobile, shake your device to fumble!</p>
<div class="shake-icon">📱↔️</div>
<p>❓ Check the help section for more information</p>
</div>
</div>
</body>
</html>

View file

@ -411,4 +411,100 @@ html, body {
button {
min-width: 44px;
min-height: 44px;
}
.permission-button {
display: block;
margin: 20px auto 0;
padding: 10px 20px;
background-color: #ff4500;
color: white;
border: none;
border-radius: 20px;
font-size: 14px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.dark-mode .permission-button {
background-color: #ff6b4a;
}
.permission-button:hover {
background-color: #ff5722;
}
@media (hover: none) {
.permission-button:hover {
background-color: #ff4500;
}
.dark-mode .permission-button:hover {
background-color: #ff6b4a;
}
}
.warning-modal .modal-content {
max-width: 400px;
}
.warning-modal h2 {
color: #ff4500;
display: flex;
align-items: center;
gap: 10px;
justify-content: center;
}
.cooldown-timer {
background: rgba(255, 69, 0, 0.1);
padding: 15px;
border-radius: 8px;
margin-top: 20px;
font-weight: bold;
color: #ff4500;
}
.dark-mode .cooldown-timer {
background: rgba(255, 107, 74, 0.1);
color: #ff6b4a;
}
@media (max-width: 768px) {
.warning-modal .modal-content {
width: 90%;
margin: -300px auto 0;
}
}
.warning-close-btn {
display: block;
width: 100%;
padding: 12px;
margin-top: 20px;
background-color: #ff4500;
color: white;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
transition: background-color 0.3s ease, opacity 0.3s ease;
}
.warning-close-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.dark-mode .warning-close-btn {
background-color: #ff6b4a;
}
.warning-close-btn:not(:disabled):hover {
background-color: #ff5722;
}
.dark-mode .warning-close-btn:not(:disabled):hover {
background-color: #ff7c5c;
}