Skip to content

Commit 2bdd13e

Browse files
committed
chore: bump version from 7.3.11 to 7.3.12 and fix tooltip positioning issues in the history page
1 parent 3ada114 commit 2bdd13e

File tree

4 files changed

+125
-128
lines changed

4 files changed

+125
-128
lines changed

.github/MEMORY.md

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
2. **Countdown Timer Startup** - Changed "Error Loading" to "Waiting for Cycle" during startup
1111
3. **Reset Button Behavior** - Improved "Refreshing" feedback to stay until genuinely new data is available
1212
4. **Sonarr Season Packs API Fix** - Fixed double-counting of API calls in season packs mode
13-
5. **Development Guidelines** - Added version number management guidelines
13+
5. **History Page Tooltip Fix** - Fixed JSON popup tooltips being obscured after page refresh
14+
6. **Development Guidelines** - Added version number management guidelines
1415

1516
**Files Modified:**
1617
- `frontend/static/js/new-main.js` - Low usage mode detection and stats display fixes
@@ -19,6 +20,8 @@
1920
- `src/primary/stats_manager.py` - Added stats-only increment function
2021
- `src/primary/apps/sonarr/missing.py` - Fixed season pack stats tracking
2122
- `src/primary/apps/sonarr/upgrade.py` - Fixed season pack stats tracking
23+
- `frontend/static/js/history.js` - Fixed tooltip positioning and z-index issues
24+
- `frontend/templates/components/history_section.html` - Simplified tooltip CSS
2225
- `.github/listen.MD` - Added version number management guidelines
2326

2427
**Tags:** ["major_release", "ui_improvements", "low_usage_mode", "countdown_timers", "api_limits", "sonarr", "user_experience"]
@@ -206,4 +209,78 @@ for i in range(episode_count):
206209

207210
**Tags:** ["bug_fix", "backend", "sonarr", "api_limits", "season_packs", "stats_tracking"]
208211

212+
## Bug Fix: History Page Tooltip Obscured After Page Refresh (v7.3.10)
213+
214+
**Date:** 2025-05-25
215+
**Issue:** JSON popup tooltips in the History page get obscured by other menu items after a page refresh/reload. The tooltip displays correctly initially but becomes hidden behind other elements after refreshing the page.
216+
**Root Cause:** The tooltip was using `position: absolute` and being appended as a child of the info icon, which created stacking context issues. After page refresh, the z-index wasn't being properly enforced, causing the tooltip to appear behind other page elements.
217+
218+
**Solution:**
219+
1. **Changed positioning approach** - Switched from `position: absolute` to `position: fixed` to escape stacking context issues
220+
2. **Moved tooltip to document body** - Instead of appending to the icon, append to `document.body` for proper positioning
221+
3. **Simplified CSS** - Removed complex background layers and animations that were causing conflicts
222+
4. **Enhanced JavaScript positioning** - Added proper viewport boundary detection and positioning logic
223+
5. **Removed CSS hover rules** - Handled all tooltip display logic through JavaScript for better control
224+
225+
**Files Modified:**
226+
- `frontend/static/js/history.js` - Fixed tooltip positioning and event handling
227+
- `frontend/templates/components/history_section.html` - Simplified tooltip CSS
228+
229+
**Code Changes:**
230+
```javascript
231+
// Before: Tooltip appended to icon with absolute positioning
232+
infoIcon.appendChild(tooltip);
233+
tooltip.style.position = 'absolute';
234+
235+
// After: Tooltip appended to body with fixed positioning
236+
document.body.appendChild(tooltip);
237+
tooltip.style.position = 'fixed';
238+
239+
// Enhanced positioning logic
240+
infoIcon.addEventListener('mouseenter', (e) => {
241+
const iconRect = infoIcon.getBoundingClientRect();
242+
243+
// Position tooltip near the icon using fixed positioning
244+
tooltip.style.left = (iconRect.right + 10) + 'px';
245+
tooltip.style.top = iconRect.top + 'px';
246+
247+
// Adjust if tooltip would go off screen
248+
const tooltipWidth = 350;
249+
if (iconRect.right + tooltipWidth + 10 > window.innerWidth) {
250+
tooltip.style.left = (iconRect.left - tooltipWidth - 10) + 'px';
251+
}
252+
253+
// Adjust if tooltip would go off bottom of screen
254+
const tooltipHeight = 300;
255+
if (iconRect.top + tooltipHeight > window.innerHeight) {
256+
tooltip.style.top = (window.innerHeight - tooltipHeight - 10) + 'px';
257+
}
258+
259+
tooltip.style.display = 'block';
260+
});
261+
```
262+
263+
**CSS Changes:**
264+
```css
265+
/* Before: Complex positioning with multiple layers */
266+
.json-tooltip {
267+
position: absolute !important;
268+
/* Complex background layers and animations */
269+
}
270+
271+
/* After: Simple fixed positioning */
272+
.json-tooltip {
273+
display: none;
274+
position: fixed; /* Use fixed positioning to escape stacking context issues */
275+
z-index: 999999; /* Very high z-index */
276+
pointer-events: none; /* Prevent tooltip from interfering with mouse events */
277+
}
278+
```
279+
280+
**Impact:** Tooltips now display correctly both on initial page load and after page refresh, with proper positioning that respects viewport boundaries.
281+
282+
**Testing:** Verified that container starts successfully and tooltips work properly in all scenarios.
283+
284+
**Tags:** ["bug_fix", "frontend", "history_page", "tooltips", "z_index", "positioning", "ui_improvement"]
285+
209286
---

frontend/static/js/history.js

Lines changed: 35 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -263,38 +263,7 @@ const historyModule = {
263263
// Create tooltip element for JSON data
264264
const tooltip = document.createElement('div');
265265
tooltip.className = 'json-tooltip';
266-
267-
// Add a solid background backing div to ensure no transparency
268-
const solidBackground = document.createElement('div');
269-
solidBackground.style.position = 'absolute';
270-
solidBackground.style.top = '0';
271-
solidBackground.style.left = '0';
272-
solidBackground.style.width = '100%';
273-
solidBackground.style.height = '100%';
274-
solidBackground.style.backgroundColor = '#121824'; // Solid dark background
275-
solidBackground.style.zIndex = '1';
276-
solidBackground.style.borderRadius = '5px';
277-
tooltip.appendChild(solidBackground);
278-
279-
// Add another solid layer for extra opacity
280-
const extraLayer = document.createElement('div');
281-
extraLayer.style.position = 'absolute';
282-
extraLayer.style.top = '0';
283-
extraLayer.style.left = '0';
284-
extraLayer.style.width = '100%';
285-
extraLayer.style.height = '100%';
286-
extraLayer.style.backgroundColor = '#0c111d';
287-
extraLayer.style.opacity = '0.9';
288-
extraLayer.style.zIndex = '2';
289-
extraLayer.style.borderRadius = '5px';
290-
tooltip.appendChild(extraLayer);
291-
292-
// Create a container for content that sits above the background
293-
const contentContainer = document.createElement('div');
294-
contentContainer.style.position = 'relative';
295-
contentContainer.style.zIndex = '5'; // Higher z-index to ensure content is on top
296-
contentContainer.style.pointerEvents = 'auto';
297-
tooltip.appendChild(contentContainer);
266+
tooltip.style.display = 'none';
298267

299268
// Format the JSON data for display
300269
let jsonData = {};
@@ -318,41 +287,42 @@ const historyModule = {
318287
const pre = document.createElement('pre');
319288
pre.className = 'json-content';
320289
pre.textContent = JSON.stringify(jsonData, null, 2);
321-
contentContainer.appendChild(pre);
290+
tooltip.appendChild(pre);
322291

323-
// Add the tooltip to the icon
324-
infoIcon.appendChild(tooltip);
292+
// Add the tooltip to the document body for fixed positioning
293+
document.body.appendChild(tooltip);
294+
295+
// Add hover events with proper positioning
296+
infoIcon.addEventListener('mouseenter', (e) => {
297+
const iconRect = infoIcon.getBoundingClientRect();
298+
299+
// Position tooltip near the icon using fixed positioning
300+
tooltip.style.left = (iconRect.right + 10) + 'px';
301+
tooltip.style.top = iconRect.top + 'px';
302+
303+
// Adjust if tooltip would go off screen
304+
const tooltipWidth = 350;
305+
if (iconRect.right + tooltipWidth + 10 > window.innerWidth) {
306+
tooltip.style.left = (iconRect.left - tooltipWidth - 10) + 'px';
307+
}
308+
309+
// Adjust if tooltip would go off bottom of screen
310+
const tooltipHeight = 300; // max-height from CSS
311+
if (iconRect.top + tooltipHeight > window.innerHeight) {
312+
tooltip.style.top = (window.innerHeight - tooltipHeight - 10) + 'px';
313+
}
314+
315+
tooltip.style.display = 'block';
316+
});
317+
318+
// Add mouse leave event to hide tooltip
319+
infoIcon.addEventListener('mouseleave', () => {
320+
tooltip.style.display = 'none';
321+
});
325322

326-
// Add positioning logic to prevent the tooltip from being cut off
327-
infoIcon.addEventListener('mouseenter', () => {
328-
setTimeout(() => {
329-
// Get positions
330-
const iconRect = infoIcon.getBoundingClientRect();
331-
const tooltipRect = tooltip.getBoundingClientRect();
332-
const viewportWidth = window.innerWidth;
333-
334-
// Position the tooltip to the right of the icon by default
335-
let leftPos = 35; // Start with offset to the right
336-
let topPos = '100%';
337-
338-
// If tooltip would go off the right edge
339-
if (iconRect.left + tooltipRect.width > viewportWidth) {
340-
// Move it to the left so it stays within the viewport
341-
const overflow = iconRect.left + tooltipRect.width - viewportWidth;
342-
leftPos = -overflow - 20; // 20px padding from edge
343-
}
344-
345-
// Check if tooltip would go off the bottom edge
346-
const viewportHeight = window.innerHeight;
347-
if (iconRect.bottom + tooltipRect.height > viewportHeight) {
348-
// Position above the icon instead
349-
topPos = `-${tooltipRect.height}px`;
350-
}
351-
352-
// Apply the calculated positions
353-
tooltip.style.left = `${leftPos}px`;
354-
tooltip.style.top = topPos;
355-
}, 0);
323+
// Also hide tooltip when mouse enters the tooltip itself and then leaves
324+
tooltip.addEventListener('mouseleave', () => {
325+
tooltip.style.display = 'none';
356326
});
357327

358328
// Create a container div to hold both icon and title on the same line

frontend/templates/components/history_section.html

Lines changed: 11 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -598,86 +598,36 @@
598598
/* Hide the tooltip by default */
599599
.json-tooltip {
600600
display: none;
601-
position: absolute;
602-
left: 35px; /* Move the tooltip to the right by default */
603-
top: 100%;
604-
/* Extra thick solid background with absolutely no transparency */
601+
position: fixed; /* Use fixed positioning to escape stacking context issues */
602+
left: 0;
603+
top: 0;
605604
background-color: #121824;
606-
/* Add a thick dark background behind content */
607-
background-image:
608-
linear-gradient(to bottom,
609-
#121824 0%,
610-
#0c111d 100%);
611-
/* Double border for better definition */
612-
border: 3px solid #2185d0;
605+
border: 2px solid #2185d0;
613606
border-radius: 8px;
614607
padding: 10px;
615608
width: 350px;
616609
max-height: 300px;
617610
overflow-y: auto;
618-
z-index: 999999; /* Super high z-index */
611+
z-index: 999999; /* Very high z-index */
619612
font-family: monospace;
620613
font-size: 12px;
621-
color: #ffffff; /* Pure white text */
614+
color: #ffffff;
622615
text-align: left;
623616
white-space: pre-wrap;
624-
/* Force complete opacity */
625-
opacity: 1 !important;
626-
/* Strong glow effect similar to Huntarr logo - more pronounced */
627-
box-shadow:
628-
0 0 0 4px #121824, /* Thick barrier */
629-
0 0 0 5px #2185d0, /* Border highlight */
630-
0 0 20px 5px #2185d0, /* Much stronger blue glow */
631-
0 5px 15px rgba(0, 0, 0, 0.9); /* Deep shadow */
632-
/* Animation for the glow effect - faster to be more noticeable */
633-
animation: tooltipGlow 2s ease-in-out infinite alternate;
634-
}
635-
636-
/* Glowing border animation */
637-
@keyframes tooltipGlow {
638-
0% {
639-
box-shadow:
640-
0 0 0 4px #121824, /* Solid barrier */
641-
0 0 0 5px #2185d0, /* Blue border */
642-
0 0 25px 8px #2185d0, /* Much stronger blue glow */
643-
0 5px 15px rgba(0, 0, 0, 0.9); /* Deep shadow */
644-
border-color: #2185d0;
645-
}
646-
50% {
647-
box-shadow:
648-
0 0 0 4px #121824, /* Solid barrier */
649-
0 0 0 5px #9b59b6, /* Brighter purple border */
650-
0 0 25px 8px #9b59b6, /* Much stronger purple glow */
651-
0 5px 15px rgba(0, 0, 0, 0.9); /* Deep shadow */
652-
border-color: #9b59b6;
653-
}
654-
100% {
655-
box-shadow:
656-
0 0 0 4px #121824, /* Solid barrier */
657-
0 0 0 5px #2185d0, /* Blue border */
658-
0 0 25px 8px #2185d0, /* Much stronger blue glow */
659-
0 5px 15px rgba(0, 0, 0, 0.9); /* Deep shadow */
660-
border-color: #2185d0;
661-
}
617+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.8);
618+
pointer-events: none; /* Prevent tooltip from interfering with mouse events */
662619
}
663620

621+
622+
664623
/* Style the JSON content */
665624
.json-content {
666625
margin: 0;
667626
white-space: pre-wrap;
668627
word-break: break-word;
669628
}
670629

671-
/* Show tooltip on hover */
672-
.info-hover-icon:hover .json-tooltip {
673-
display: block;
674-
animation: fadeIn 0.3s ease;
675-
}
676-
677-
@keyframes fadeIn {
678-
from { opacity: 0; transform: translateY(-10px); }
679-
to { opacity: 1; transform: translateY(0); }
680-
}
630+
681631

682632
/* Processed title styling */
683633
.processed-title {

version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7.3.11
1+
7.3.12

0 commit comments

Comments
 (0)