diff --git a/app/layout.tsx b/app/layout.tsx
index c3da363..d8ed1e0 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -77,6 +77,19 @@ export default function RootLayout({
}>) {
return (
+
+ {/* PWA Manifest */}
+
+ {/* Apple PWA Support */}
+
+
+
+
+ {/* Theme Color (for browser address bar) */}
+
+ {/* Mobile viewport */}
+
+
(null);
- const [menuPosition, setMenuPosition] = React.useState({ top: 0, left: 0 });
+ const menuRef = React.useRef(null);
+ const [menuPosition, setMenuPosition] = React.useState({ top: 0, left: 0, maxHeight: 'none', openUpward: false });
const [isAdFilterOpen, setAdFilterOpen] = React.useState(false);
const AD_FILTER_LABELS: Record = {
@@ -62,23 +63,61 @@ export function DesktopMoreMenu({
React.useEffect(() => {
const updateFullscreen = () => {
- setIsFullscreen(!!document.fullscreenElement);
+ // Check both native fullscreen and window fullscreen (CSS-based)
+ const nativeFullscreen = !!document.fullscreenElement;
+ const windowFullscreen = containerRef.current?.closest('.is-web-fullscreen') !== null;
+ setIsFullscreen(nativeFullscreen || windowFullscreen);
};
document.addEventListener('fullscreenchange', updateFullscreen);
+ // Also check periodically for window fullscreen changes (CSS class based)
+ const interval = setInterval(updateFullscreen, 500);
updateFullscreen();
- return () => document.removeEventListener('fullscreenchange', updateFullscreen);
- }, []);
+ return () => {
+ document.removeEventListener('fullscreenchange', updateFullscreen);
+ clearInterval(interval);
+ };
+ }, [containerRef]);
- React.useEffect(() => {
- if (showMoreMenu && buttonRef.current && containerRef.current) {
- const buttonRect = buttonRef.current.getBoundingClientRect();
- const containerRect = containerRef.current.getBoundingClientRect();
+ // Calculate menu position with available space awareness
+ const calculateMenuPosition = React.useCallback(() => {
+ if (!buttonRef.current || !containerRef.current) return;
+
+ const buttonRect = buttonRef.current.getBoundingClientRect();
+ const containerRect = containerRef.current.getBoundingClientRect();
+ const viewportHeight = window.innerHeight;
+
+ // Space available below and above the button
+ const spaceBelow = viewportHeight - buttonRect.bottom - 20; // 20px margin
+ const spaceAbove = buttonRect.top - containerRect.top - 20;
+
+ // Estimate menu height (or use actual if already rendered)
+ const estimatedMenuHeight = 450; // approximate height of menu
+ const actualMenuHeight = menuRef.current?.offsetHeight || estimatedMenuHeight;
+
+ // Determine if we should open upward
+ const openUpward = spaceBelow < Math.min(actualMenuHeight, 300) && spaceAbove > spaceBelow;
+
+ // Calculate max-height based on available space
+ const maxHeight = openUpward
+ ? Math.min(spaceAbove, actualMenuHeight)
+ : Math.min(spaceBelow, viewportHeight * 0.7);
+
+ if (openUpward) {
+ setMenuPosition({
+ top: buttonRect.top - containerRect.top - 10, // Position above button
+ left: buttonRect.left - containerRect.left,
+ maxHeight: `${maxHeight}px`,
+ openUpward: true
+ });
+ } else {
setMenuPosition({
top: buttonRect.bottom - containerRect.top + 10,
- left: buttonRect.left - containerRect.left
+ left: buttonRect.left - containerRect.left,
+ maxHeight: `${maxHeight}px`,
+ openUpward: false
});
}
- }, [showMoreMenu, containerRef]);
+ }, [containerRef]);
// Auto-close menu on scroll
React.useEffect(() => {
@@ -92,25 +131,32 @@ export function DesktopMoreMenu({
return () => window.removeEventListener('scroll', handleScroll);
}, [showMoreMenu, onToggleMoreMenu]);
+ // Recalculate position when menu opens
+ React.useEffect(() => {
+ if (showMoreMenu) {
+ calculateMenuPosition();
+ // Recalculate after a small delay to get actual menu height
+ const timer = setTimeout(calculateMenuPosition, 50);
+ return () => clearTimeout(timer);
+ }
+ }, [showMoreMenu, calculateMenuPosition]);
+
const handleToggle = () => {
- if (!showMoreMenu && buttonRef.current && containerRef.current) {
- const buttonRect = buttonRef.current.getBoundingClientRect();
- const containerRect = containerRef.current.getBoundingClientRect();
- setMenuPosition({
- top: buttonRect.bottom - containerRect.top + 10,
- left: buttonRect.left - containerRect.left
- });
+ if (!showMoreMenu) {
+ calculateMenuPosition();
}
onToggleMoreMenu();
};
const MenuContent = (