-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmenu-manager.js
More file actions
155 lines (131 loc) · 4.37 KB
/
Copy pathmenu-manager.js
File metadata and controls
155 lines (131 loc) · 4.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// menu-manager.js - Centralized menu visibility controller
/**
* MenuManager - Controls menu button visibility across all channels
* Ensures the menu button remains accessible regardless of active channel
*/
export const MenuManager = {
/**
* Initialize the menu manager
*/
init() {
this.menuButton = document.getElementById('menuButton');
this.tvGuide = document.getElementById('tvGuide');
this.header = document.getElementById('header');
this.closeGuide = document.getElementById('closeGuide');
this.bindEvents();
// Don't show on initialization - will show based on header visibility
},
/**
* Bind event listeners for channel changes and menu interactions
*/
bindEvents() {
// Listen for channel change events
document.addEventListener('channelChanged', () => {
this.show();
});
// Set up menu button click handler
if (this.menuButton) {
this.menuButton.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
this.toggleTVGuide();
});
}
// Set up close guide button handler
if (this.closeGuide) {
this.closeGuide.addEventListener('click', (e) => {
e.preventDefault();
this.hideTVGuide();
});
}
},
/**
* Set up an observer to detect changes that might hide the menu
*/
createVisibilityObserver() {
if (!this.menuButton) return;
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.attributeName === 'style') {
// If style changes and menu is hidden, show it
const computedStyle = window.getComputedStyle(this.menuButton);
if (computedStyle.display === 'none' || parseFloat(computedStyle.opacity) < 0.5) {
this.show();
}
}
});
});
observer.observe(this.menuButton, { attributes: true });
},
/**
* Show the menu button only when header is visible - exact header behavior
*/
show() {
if (!this.menuButton || !this.header) return;
// Get header computed style
const headerStyle = window.getComputedStyle(this.header);
const isHeaderVisible = headerStyle.display !== 'none' && parseFloat(headerStyle.opacity) > 0.5;
// ONLY show menu button if header is visible and the guide is not already open.
if (isHeaderVisible && !document.body.classList.contains('tv-guide-active')) {
// EXACTLY match header visibility
this.menuButton.style.display = headerStyle.display;
this.menuButton.style.opacity = headerStyle.opacity;
this.menuButton.style.visibility = headerStyle.visibility;
this.menuButton.style.pointerEvents = 'auto';
// Ensure proper position. CSS owns mobile sizing/placement.
this.menuButton.style.position = "fixed";
this.menuButton.style.zIndex = "999999";
this.menuButton.style.pointerEvents = 'auto';
// Ensure tap target size without forcing desktop-like mobile chrome.
this.menuButton.style.minHeight = "38px";
this.menuButton.style.minWidth = "44px";
} else {
// Hide menu when header is hidden
this.menuButton.style.display = 'none';
this.menuButton.style.opacity = '0';
this.menuButton.style.visibility = 'hidden';
}
},
/**
* Check and enforce menu visibility
*/
ensureVisibility() {
// Refresh references
this.menuButton = document.getElementById('menuButton');
this.header = document.getElementById('header');
// Sync with header visibility
this.show();
},
/**
* Add header visibility observer
*/
createHeaderObserver() {
if (!this.header) return;
const observer = new MutationObserver(() => {
// When header style changes, sync menu button visibility
this.show();
});
observer.observe(this.header, { attributes: true });
},
/**
* Toggle TV Guide visibility - delegate to global implementation in script.js
*/
toggleTVGuide() {
if (typeof window.toggleTVGuide === 'function') {
window.toggleTVGuide();
}
},
/**
* Hide TV Guide (for close button) - delegate
*/
hideTVGuide() {
if (typeof window.toggleTVGuide === 'function') {
window.toggleTVGuide(false);
}
}
};
// Create a custom event for channel changes
export const notifyChannelChanged = () => {
const event = new CustomEvent('channelChanged');
document.dispatchEvent(event);
};