Added settings side panel.

Working on open in new tab.
This commit is contained in:
Michael Andrew Maurakis 2025-01-20 01:10:03 -06:00
parent fd88979c32
commit ad05afbb83
2 changed files with 293 additions and 27 deletions

View file

@ -32,7 +32,6 @@
</div> </div>
<div class="header-buttons"> <div class="header-buttons">
<div class="social-buttons"> <div class="social-buttons">
<button id="helpButton"></button>
<button id="donateButton">💝</button> <button id="donateButton">💝</button>
<button id="githubButton"> <button id="githubButton">
<svg viewBox="0 0 24 24" width="24" height="24"> <svg viewBox="0 0 24 24" width="24" height="24">
@ -41,20 +40,56 @@
</button> </button>
</div> </div>
<div class="app-controls"> <div class="app-controls">
<div class="theme-toggle"> <button id="settingsButton">
<button id="darkModeToggle">🌙</button> <svg viewBox="0 0 24 24" width="24" height="24">
</div> <path fill="currentColor" d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.07.62-.07.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/>
</svg>
</button>
<button id="fumbleButton">Fumble!</button> <button id="fumbleButton">Fumble!</button>
</div> </div>
</div> </div>
</header> </header>
<div id="helpModal" class="modal"> <div id="settingsPanel" class="settings-panel">
<div class="modal-content"> <div class="settings-content">
<span class="close-button">&times;</span> <div class="settings-header">
<h2>Disclaimer</h2> <h2>Settings</h2>
<p>FumbleAround uses Wiby.me's search engine to provide random web pages. We are not responsible for the content that appears. Use at your own discretion.</p> <button class="close-settings">×</button>
<p>This project is a homage to the classic StumbleUpon, reimagined for the modern web.</p> </div>
<div class="settings-section">
<h3>Display</h3>
<div class="setting-item">
<label>Dark Mode</label>
<button id="darkModeToggle">🌙</button>
</div>
</div>
<div class="settings-section">
<h3>Actions</h3>
<div class="setting-item">
<button id="openInNewWindow" class="settings-button">Open in New Window</button>
</div>
</div>
<div class="settings-section">
<h3>About</h3>
<div class="setting-item about-section">
<div class="about-content">
<div class="about-logo">
<img src="./Assets/smily.png" alt="FumbleAround Logo">
<h4>FumbleAround</h4>
</div>
<div class="about-text">
<p>Discover the hidden gems of the internet, powered by Wiby.me's search engine.</p>
<div class="disclaimer">
<h5>Disclaimer</h5>
<p>We are not responsible for the content that appears. Use at your own discretion.</p>
</div>
<div class="tribute">
<p>A homage to the classic StumbleUpon, reimagined for the modern web.</p>
</div>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
@ -93,6 +128,7 @@
let lastFumbleTime = 0; let lastFumbleTime = 0;
const cooldownPeriod = 5000; // 5 seconds cooldown const cooldownPeriod = 5000; // 5 seconds cooldown
let cooldownTimer = null; let cooldownTimer = null;
let currentPageUrl = null; // Add this to store the current URL
const fumble = () => { const fumble = () => {
const currentTime = Date.now(); const currentTime = Date.now();
@ -132,20 +168,23 @@
// Wait for the page to load then focus // Wait for the page to load then focus
frame.onload = () => { frame.onload = () => {
// Check if we landed on a blocked/error page
try { try {
// Store the actual URL after redirect
currentPageUrl = frame.contentWindow.location.href;
const title = frame.contentWindow.document.title.toLowerCase(); const title = frame.contentWindow.document.title.toLowerCase();
if (title.includes('blocked') || if (title.includes('blocked') ||
title.includes('error') || title.includes('error') ||
title.includes('refused') || title.includes('refused') ||
title.includes('cannot') || title.includes('cannot') ||
title.includes('denied')) { title.includes('denied')) {
// Try again if we hit an error page currentPageUrl = null; // Reset if we hit an error
fumble(); fumble();
return; return;
} }
} catch (e) { } catch (e) {
// Can't access title due to CORS - assume page is OK // Can't access due to CORS
currentPageUrl = null;
} }
frame.focus(); frame.focus();
@ -191,17 +230,25 @@
window.open('https://wiby.me/donate/', '_blank'); window.open('https://wiby.me/donate/', '_blank');
}); });
// Add help button click handler // Add settings button click handler
const modal = document.getElementById('helpModal'); const settingsPanel = document.getElementById('settingsPanel');
const helpButton = document.getElementById('helpButton'); const settingsButton = document.getElementById('settingsButton');
const closeButton = document.querySelector('.close-button'); const closeSettings = document.querySelector('.close-settings');
helpButton.addEventListener('click', () => { settingsButton.addEventListener('click', () => {
modal.classList.add('show'); settingsPanel.classList.add('show');
});
closeSettings.addEventListener('click', () => {
settingsPanel.classList.remove('show');
}); });
closeButton.addEventListener('click', () => { // Update the open in new window handler
modal.classList.remove('show'); document.getElementById('openInNewWindow').addEventListener('click', () => {
if (currentPageUrl) {
window.open(currentPageUrl, '_blank');
settingsPanel.classList.remove('show');
}
}); });
// Update warning modal close handler // Update warning modal close handler
@ -217,8 +264,8 @@
// Remove the click-outside-to-close functionality for warning modal // Remove the click-outside-to-close functionality for warning modal
window.addEventListener('click', (event) => { window.addEventListener('click', (event) => {
if (event.target === modal) { // Only for help modal if (event.target === warningModal) { // Only for warning modal
modal.classList.remove('show'); warningModal.classList.remove('show');
} }
}); });
@ -283,15 +330,15 @@
if ('DeviceMotionEvent' in window) { if ('DeviceMotionEvent' in window) {
// Add a button to request permission on iOS // Add a button to request permission on iOS
if (typeof DeviceMotionEvent.requestPermission === 'function') { if (typeof DeviceMotionEvent.requestPermission === 'function') {
const modal = document.getElementById('helpModal'); const settingsPanel = document.getElementById('settingsPanel');
const modalContent = modal.querySelector('.modal-content'); const settingsContent = settingsPanel.querySelector('.settings-content');
const permissionButton = document.createElement('button'); const permissionButton = document.createElement('button');
permissionButton.textContent = 'Enable Shake to Fumble'; permissionButton.textContent = 'Enable Shake to Fumble';
permissionButton.className = 'permission-button'; permissionButton.className = 'permission-button';
permissionButton.addEventListener('click', initShakeDetection); permissionButton.addEventListener('click', initShakeDetection);
modalContent.appendChild(permissionButton); settingsContent.appendChild(permissionButton);
} else { } else {
// Automatically start for non-iOS devices // Automatically start for non-iOS devices
initShakeDetection(); initShakeDetection();

View file

@ -507,4 +507,223 @@ button {
.dark-mode .warning-close-btn:not(:disabled):hover { .dark-mode .warning-close-btn:not(:disabled):hover {
background-color: #ff7c5c; background-color: #ff7c5c;
}
.settings-panel {
position: fixed;
top: 0;
right: -400px;
width: 400px;
height: 100vh;
background-color: #ffffff;
box-shadow: -2px 0 10px rgba(0,0,0,0.1);
transition: right 0.3s ease;
z-index: 2000;
overflow-y: auto;
}
.dark-mode .settings-panel {
background-color: #1a1a1a;
color: #ffffff;
}
.settings-panel.show {
right: 0;
}
.settings-content {
padding: 20px;
}
.settings-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
.dark-mode .settings-header {
border-bottom-color: #333;
}
.close-settings {
background: none;
border: none;
font-size: 24px;
cursor: pointer;
color: #666;
padding: 5px;
}
.dark-mode .close-settings {
color: #999;
}
.settings-section {
margin-bottom: 30px;
}
.settings-section h3 {
margin-bottom: 15px;
color: #ff4500;
}
.dark-mode .settings-section h3 {
color: #ff6b4a;
}
.setting-item {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
padding: 10px;
background: #f5f5f5;
border-radius: 8px;
}
.dark-mode .setting-item {
background: #2a2a2a;
}
.settings-button {
width: 100%;
padding: 10px;
background-color: #ff4500;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.dark-mode .settings-button {
background-color: #ff6b4a;
}
.settings-button:hover {
background-color: #ff5722;
}
@media (max-width: 768px) {
.settings-panel {
width: 100%;
right: -100%;
}
}
#settingsButton {
padding: 8px;
background-color: transparent;
border: none;
cursor: pointer;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.2s;
}
#settingsButton svg {
width: 24px;
height: 24px;
color: #333;
transition: color 0.3s ease, transform 0.3s ease;
}
.dark-mode #settingsButton svg {
color: #fff;
}
#settingsButton:hover svg {
transform: rotate(30deg);
}
#settingsButton:active svg {
transform: rotate(180deg);
}
@media (hover: none) {
#settingsButton:hover svg {
transform: none;
}
}
.about-section {
flex-direction: column;
padding: 20px;
}
.about-content {
width: 100%;
text-align: center;
}
.about-logo {
margin-bottom: 20px;
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
}
.about-logo img {
width: 64px;
height: 64px;
border-radius: 12px;
}
.about-logo h4 {
font-size: 1.2em;
margin: 0;
color: #ff4500;
}
.dark-mode .about-logo h4 {
color: #ff6b4a;
}
.about-text {
display: flex;
flex-direction: column;
gap: 20px;
}
.about-text p {
margin: 0;
line-height: 1.5;
}
.disclaimer {
background: rgba(255, 69, 0, 0.1);
padding: 15px;
border-radius: 8px;
margin: 10px 0;
}
.dark-mode .disclaimer {
background: rgba(255, 107, 74, 0.1);
}
.disclaimer h5 {
color: #ff4500;
margin: 0 0 10px 0;
font-size: 1em;
}
.dark-mode .disclaimer h5 {
color: #ff6b4a;
}
.tribute {
font-style: italic;
opacity: 0.8;
padding-top: 10px;
border-top: 1px solid rgba(0, 0, 0, 0.1);
}
.dark-mode .tribute {
border-top-color: rgba(255, 255, 255, 0.1);
} }