Fix navigation menu bugs in 0.9.8
Fixed Issues:
1. Icon rendering - Replaced emoji 🔑 with SVG key icon for better compatibility
2. JavaScript errors - Added try/catch blocks throughout navigation menu code
3. Sites not loading - Fixed IPC communication with extensive error logging
4. Menu becoming part of rotation - Ensured proper overlay with z-index and pointer-events
5. Missing auto-dismiss - Added 30-second timeout that auto-closes menu
6. Improved close button positioning - Moved to top-right with better visibility
Technical Changes:
- Changed navButton.innerHTML from emoji to SVG path for key icon
- Added NAV_MENU_TIMEOUT constant (30000ms)
- Added navMenuTimer variable for timeout management
- Enhanced createNavMenu() with console logging and error handling
- Fixed content positioning with 'position:relative'
- Added pointer-events:auto to ensure menu captures events
- Enhanced showNavMenu() with try/catch and 30-second auto-dismiss timer
- Enhanced hideNavMenu() with timer cleanup and error handling
- Enhanced toggleNavMenu() with logging
- Fixed loadSitesIntoNav() with error handling
- Enhanced config-data IPC handler with extensive logging and validation
- Changed siteBtn.innerHTML to siteBtn.textContent to prevent XSS
- Added user-select:none to prevent text selection on buttons
- Added stopPropagation to content to prevent background clicks from closing
- Fixed close button event handler with proper logging
Console Output:
- All navigation menu actions now log to console with [NAV] prefix
- Helps diagnose issues: button clicks, menu show/hide, config requests, site loading
- Error messages clearly identify failure points
This should resolve all reported issues with the navigation menu.
This commit is contained in:
+102
-16
@@ -6181,6 +6181,8 @@ let navButtonEnabled=true;
|
|||||||
let navButton=null;
|
let navButton=null;
|
||||||
let navMenu=null;
|
let navMenu=null;
|
||||||
let navMenuVisible=false;
|
let navMenuVisible=false;
|
||||||
|
let navMenuTimer=null;
|
||||||
|
const NAV_MENU_TIMEOUT=30000; // 30 seconds
|
||||||
|
|
||||||
// Listen for pause button visibility control from main process
|
// Listen for pause button visibility control from main process
|
||||||
// CRITICAL: This must be outside DOMContentLoaded so it doesn't reset on page load
|
// CRITICAL: This must be outside DOMContentLoaded so it doesn't reset on page load
|
||||||
@@ -6319,20 +6321,26 @@ window.addEventListener('DOMContentLoaded',()=>{
|
|||||||
|
|
||||||
navButton=document.createElement('div');
|
navButton=document.createElement('div');
|
||||||
navButton.id='electron-nav-button';
|
navButton.id='electron-nav-button';
|
||||||
navButton.innerHTML='🔑';
|
// Use SVG key icon instead of emoji for better compatibility
|
||||||
|
navButton.innerHTML='<svg width="32" height="32" viewBox="0 0 24 24" fill="white"><path d="M12.65 10C11.7 7.31 8.9 5.5 5.77 6.12c-2.29.46-4.15 2.29-4.63 4.58C.32 14.57 3.26 18 7 18c2.61 0 4.83-1.67 5.65-4H17v2c0 1.1.9 2 2 2s2-.9 2-2v-2c1.1 0 2-.9 2-2s-.9-2-2-2h-8.35zM7 14c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/></svg>';
|
||||||
navButton.title='Navigation Menu';
|
navButton.title='Navigation Menu';
|
||||||
navButton.style.cssText=`
|
navButton.style.cssText=`
|
||||||
position:fixed;top:20px;left:20px;width:60px;height:60px;
|
position:fixed;top:20px;left:20px;width:60px;height:60px;
|
||||||
background:rgba(155,89,182,0.95);border:3px solid rgba(255,255,255,0.9);
|
background:rgba(155,89,182,0.95);border:3px solid rgba(255,255,255,0.9);
|
||||||
border-radius:50%;display:none;align-items:center;justify-content:center;
|
border-radius:50%;display:none;align-items:center;justify-content:center;
|
||||||
font-size:32px;cursor:pointer;z-index:999999;
|
cursor:pointer;z-index:999999;
|
||||||
box-shadow:0 4px 12px rgba(0,0,0,0.4);user-select:none;
|
box-shadow:0 4px 12px rgba(0,0,0,0.4);user-select:none;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
navButton.addEventListener('click',(e)=>{
|
navButton.addEventListener('click',(e)=>{
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
console.log('[NAV] Button clicked');
|
||||||
|
try{
|
||||||
toggleNavMenu();
|
toggleNavMenu();
|
||||||
|
}catch(err){
|
||||||
|
console.error('[NAV] Error toggling menu:',err);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.appendChild(navButton);
|
document.body.appendChild(navButton);
|
||||||
@@ -6350,18 +6358,19 @@ window.addEventListener('DOMContentLoaded',()=>{
|
|||||||
|
|
||||||
function createNavMenu(){
|
function createNavMenu(){
|
||||||
if(navMenu)return;
|
if(navMenu)return;
|
||||||
|
console.log('[NAV] Creating navigation menu');
|
||||||
|
|
||||||
navMenu=document.createElement('div');
|
navMenu=document.createElement('div');
|
||||||
navMenu.id='electron-nav-menu';
|
navMenu.id='electron-nav-menu';
|
||||||
navMenu.style.cssText=`
|
navMenu.style.cssText=`
|
||||||
position:fixed;top:0;left:0;width:100%;height:100%;
|
position:fixed;top:0;left:0;width:100%;height:100%;
|
||||||
background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;
|
background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;
|
||||||
z-index:999998;
|
z-index:999998;pointer-events:auto;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const content=document.createElement('div');
|
const content=document.createElement('div');
|
||||||
content.style.cssText=`
|
content.style.cssText=`
|
||||||
background:rgba(44,62,80,0.98);border-radius:20px;padding:40px;
|
position:relative;background:rgba(44,62,80,0.98);border-radius:20px;padding:40px;
|
||||||
max-width:90%;max-height:90%;overflow-y:auto;
|
max-width:90%;max-height:90%;overflow-y:auto;
|
||||||
box-shadow:0 10px 40px rgba(0,0,0,0.5);
|
box-shadow:0 10px 40px rgba(0,0,0,0.5);
|
||||||
`;
|
`;
|
||||||
@@ -6369,11 +6378,17 @@ window.addEventListener('DOMContentLoaded',()=>{
|
|||||||
const closeBtn=document.createElement('div');
|
const closeBtn=document.createElement('div');
|
||||||
closeBtn.innerHTML='✕';
|
closeBtn.innerHTML='✕';
|
||||||
closeBtn.style.cssText=`
|
closeBtn.style.cssText=`
|
||||||
position:absolute;top:20px;right:20px;font-size:32px;color:white;
|
position:absolute;top:10px;right:10px;font-size:32px;color:white;
|
||||||
cursor:pointer;width:40px;height:40px;display:flex;align-items:center;
|
cursor:pointer;width:40px;height:40px;display:flex;align-items:center;
|
||||||
justify-content:center;border-radius:50%;background:rgba(231,76,60,0.8);
|
justify-content:center;border-radius:50%;background:rgba(231,76,60,0.8);
|
||||||
|
user-select:none;
|
||||||
`;
|
`;
|
||||||
closeBtn.addEventListener('click',hideNavMenu);
|
closeBtn.addEventListener('click',(e)=>{
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
console.log('[NAV] Close button clicked');
|
||||||
|
hideNavMenu();
|
||||||
|
});
|
||||||
content.appendChild(closeBtn);
|
content.appendChild(closeBtn);
|
||||||
|
|
||||||
const columns=document.createElement('div');
|
const columns=document.createElement('div');
|
||||||
@@ -6437,14 +6452,22 @@ window.addEventListener('DOMContentLoaded',()=>{
|
|||||||
|
|
||||||
navMenu.addEventListener('click',(e)=>{
|
navMenu.addEventListener('click',(e)=>{
|
||||||
if(e.target===navMenu){
|
if(e.target===navMenu){
|
||||||
|
console.log('[NAV] Background clicked, closing menu');
|
||||||
hideNavMenu();
|
hideNavMenu();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Prevent clicks inside content from closing menu
|
||||||
|
content.addEventListener('click',(e)=>{
|
||||||
|
e.stopPropagation();
|
||||||
|
});
|
||||||
|
|
||||||
document.body.appendChild(navMenu);
|
document.body.appendChild(navMenu);
|
||||||
|
console.log('[NAV] Navigation menu created and appended to body');
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleNavMenu(){
|
function toggleNavMenu(){
|
||||||
|
console.log('[NAV] Toggle menu, current state:',navMenuVisible);
|
||||||
if(navMenuVisible){
|
if(navMenuVisible){
|
||||||
hideNavMenu();
|
hideNavMenu();
|
||||||
}else{
|
}else{
|
||||||
@@ -6453,42 +6476,92 @@ window.addEventListener('DOMContentLoaded',()=>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
function showNavMenu(){
|
function showNavMenu(){
|
||||||
if(!navMenu)createNavMenu();
|
console.log('[NAV] Showing navigation menu');
|
||||||
|
try{
|
||||||
|
if(!navMenu){
|
||||||
|
createNavMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request sites data
|
||||||
loadSitesIntoNav();
|
loadSitesIntoNav();
|
||||||
|
|
||||||
navMenu.style.display='flex';
|
navMenu.style.display='flex';
|
||||||
navMenuVisible=true;
|
navMenuVisible=true;
|
||||||
|
|
||||||
|
// Set 30-second auto-dismiss timer
|
||||||
|
if(navMenuTimer){
|
||||||
|
clearTimeout(navMenuTimer);
|
||||||
|
}
|
||||||
|
navMenuTimer=setTimeout(()=>{
|
||||||
|
console.log('[NAV] Auto-dismissing menu after 30 seconds');
|
||||||
|
hideNavMenu();
|
||||||
|
},NAV_MENU_TIMEOUT);
|
||||||
|
|
||||||
|
console.log('[NAV] Menu displayed, 30-second timer started');
|
||||||
|
}catch(err){
|
||||||
|
console.error('[NAV] Error showing menu:',err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideNavMenu(){
|
function hideNavMenu(){
|
||||||
if(navMenu)navMenu.style.display='none';
|
console.log('[NAV] Hiding navigation menu');
|
||||||
|
try{
|
||||||
|
if(navMenuTimer){
|
||||||
|
clearTimeout(navMenuTimer);
|
||||||
|
navMenuTimer=null;
|
||||||
|
}
|
||||||
|
if(navMenu){
|
||||||
|
navMenu.style.display='none';
|
||||||
|
}
|
||||||
navMenuVisible=false;
|
navMenuVisible=false;
|
||||||
|
console.log('[NAV] Menu hidden');
|
||||||
|
}catch(err){
|
||||||
|
console.error('[NAV] Error hiding menu:',err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadSitesIntoNav(){
|
function loadSitesIntoNav(){
|
||||||
const sitesList=document.getElementById('nav-sites-list');
|
console.log('[NAV] Requesting config from main process');
|
||||||
if(!sitesList)return;
|
try{
|
||||||
|
|
||||||
// Request config from main process
|
|
||||||
ipcRenderer.send('get-config');
|
ipcRenderer.send('get-config');
|
||||||
|
}catch(err){
|
||||||
|
console.error('[NAV] Error requesting config:',err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ipcRenderer.on('config-data',(event,config)=>{
|
ipcRenderer.on('config-data',(event,config)=>{
|
||||||
|
console.log('[NAV] Received config data:',config);
|
||||||
|
try{
|
||||||
const sitesList=document.getElementById('nav-sites-list');
|
const sitesList=document.getElementById('nav-sites-list');
|
||||||
if(!sitesList||!config||!config.tabs)return;
|
if(!sitesList){
|
||||||
|
console.error('[NAV] Sites list element not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!config||!config.tabs){
|
||||||
|
console.error('[NAV] Invalid config data');
|
||||||
|
sitesList.innerHTML='<div style="color:white;padding:10px;">No sites configured</div>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sitesList.innerHTML='';
|
sitesList.innerHTML='';
|
||||||
|
let siteCount=0;
|
||||||
|
|
||||||
config.tabs.forEach((tab,index)=>{
|
config.tabs.forEach((tab,index)=>{
|
||||||
// Skip hidden tabs (duration === -1)
|
// Skip hidden tabs (duration === -1)
|
||||||
if(tab.duration===-1)return;
|
if(tab.duration===-1){
|
||||||
|
console.log('[NAV] Skipping hidden tab at index',index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const siteBtn=document.createElement('div');
|
const siteBtn=document.createElement('div');
|
||||||
const displayName=tab.name||tab.url;
|
const displayName=tab.name||tab.url;
|
||||||
siteBtn.innerHTML=displayName;
|
siteBtn.textContent=displayName;
|
||||||
siteBtn.style.cssText=`
|
siteBtn.style.cssText=`
|
||||||
padding:15px 20px;background:rgba(52,152,219,0.8);color:white;
|
padding:15px 20px;background:rgba(52,152,219,0.8);color:white;
|
||||||
border-radius:10px;cursor:pointer;font-size:18px;
|
border-radius:10px;cursor:pointer;font-size:18px;
|
||||||
transition:all 0.2s;border:2px solid transparent;
|
transition:all 0.2s;border:2px solid transparent;
|
||||||
|
user-select:none;
|
||||||
`;
|
`;
|
||||||
siteBtn.addEventListener('mouseenter',()=>{
|
siteBtn.addEventListener('mouseenter',()=>{
|
||||||
siteBtn.style.background='rgba(52,152,219,1)';
|
siteBtn.style.background='rgba(52,152,219,1)';
|
||||||
@@ -6498,13 +6571,26 @@ window.addEventListener('DOMContentLoaded',()=>{
|
|||||||
siteBtn.style.background='rgba(52,152,219,0.8)';
|
siteBtn.style.background='rgba(52,152,219,0.8)';
|
||||||
siteBtn.style.borderColor='transparent';
|
siteBtn.style.borderColor='transparent';
|
||||||
});
|
});
|
||||||
siteBtn.addEventListener('click',()=>{
|
siteBtn.addEventListener('click',(e)=>{
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
console.log('[NAV] Navigating to tab',index);
|
||||||
|
try{
|
||||||
ipcRenderer.send('navigate-to-tab',index);
|
ipcRenderer.send('navigate-to-tab',index);
|
||||||
hideNavMenu();
|
hideNavMenu();
|
||||||
|
}catch(err){
|
||||||
|
console.error('[NAV] Error navigating:',err);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
sitesList.appendChild(siteBtn);
|
sitesList.appendChild(siteBtn);
|
||||||
|
siteCount++;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log('[NAV] Loaded',siteCount,'sites into menu');
|
||||||
|
}catch(err){
|
||||||
|
console.error('[NAV] Error processing config data:',err);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function isTextInput(el){
|
function isTextInput(el){
|
||||||
|
|||||||
Reference in New Issue
Block a user