mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-15 17:12:59 -04:00
always there fullscreen button
This commit is contained in:
@@ -22,6 +22,7 @@ import TurnAlertListener from './components/TurnAlertListener.jsx';
|
||||
import RawUserPilePanel from './components/RawUserPilePanel.jsx';
|
||||
import ChatPanel from './components/ChatPanel.jsx';
|
||||
import FullscreenPrompt from './components/FullscreenPrompt.jsx';
|
||||
import FloatingFullscreenButton from './components/FloatingFullscreenButton.jsx';
|
||||
import { useFullscreenPrompt } from './hooks/useFullscreenPrompt.js';
|
||||
import { useSettingsNamespace } from './settings/index.js';
|
||||
import HelpOverlay from './components/HelpOverlay.jsx';
|
||||
@@ -231,8 +232,11 @@ function AppWithProviders({ layout, isDesktop, fullscreen }) {
|
||||
const {
|
||||
visible: fullscreenVisible,
|
||||
mode: fullscreenMode,
|
||||
isIOS: fullscreenIsIOS,
|
||||
nativeSupported: fullscreenNativeSupported,
|
||||
enterFullscreen,
|
||||
dismiss,
|
||||
showPrompt,
|
||||
} = fullscreen;
|
||||
|
||||
const {
|
||||
@@ -244,6 +248,8 @@ function AppWithProviders({ layout, isDesktop, fullscreen }) {
|
||||
swapMobileControlColumns: false,
|
||||
});
|
||||
const swapMobileControlColumns = Boolean(pageSettings?.swapMobileControlColumns);
|
||||
const fullscreenButtonSide = swapMobileControlColumns ? 'left' : 'right';
|
||||
const showFloatingFullscreenButton = !isDesktop && (fullscreenIsIOS || fullscreenNativeSupported);
|
||||
const [helpVisible, setHelpVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -254,6 +260,16 @@ function AppWithProviders({ layout, isDesktop, fullscreen }) {
|
||||
|
||||
const openHelp = useCallback(() => setHelpVisible(true), []);
|
||||
const closeHelp = useCallback(() => setHelpVisible(false), []);
|
||||
const handleFloatingFullscreen = useCallback(async () => {
|
||||
if (fullscreenIsIOS) {
|
||||
showPrompt();
|
||||
return;
|
||||
}
|
||||
const entered = await enterFullscreen();
|
||||
if (!entered) {
|
||||
showPrompt();
|
||||
}
|
||||
}, [enterFullscreen, fullscreenIsIOS, showPrompt]);
|
||||
const setShowOnLoad = useCallback(
|
||||
(enabled) => {
|
||||
const next = Boolean(enabled);
|
||||
@@ -299,6 +315,12 @@ function AppWithProviders({ layout, isDesktop, fullscreen }) {
|
||||
onEnterFullscreen={enterFullscreen}
|
||||
onDismiss={dismiss}
|
||||
/>
|
||||
{showFloatingFullscreenButton ? (
|
||||
<FloatingFullscreenButton
|
||||
side={fullscreenButtonSide}
|
||||
onClick={handleFloatingFullscreen}
|
||||
/>
|
||||
) : null}
|
||||
</ControlSystemProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
export default function FloatingFullscreenButton({ side = 'right', onClick }) {
|
||||
const sideClass = side === 'left' ? 'left-2' : 'right-2';
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
className={`fixed bottom-2 ${sideClass} z-30 flex h-10 w-10 items-center justify-center rounded-full border border-cyan-200/50 bg-slate-900/70 text-cyan-100 shadow-lg backdrop-blur-sm transition hover:bg-slate-800/80 active:scale-95`}
|
||||
aria-label="Enter fullscreen"
|
||||
title="Enter fullscreen"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
width="18"
|
||||
height="18"
|
||||
aria-hidden="true"
|
||||
className="pointer-events-none"
|
||||
>
|
||||
<path
|
||||
d="M4 9V4h5M15 4h5v5M20 15v5h-5M9 20H4v-5"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
@@ -53,14 +53,17 @@ export function useFullscreenPrompt(layout) {
|
||||
const isMobileLayout = MOBILE_LAYOUTS.has(layout);
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [mode, setMode] = useState('native');
|
||||
const [forceVisible, setForceVisible] = useState(false);
|
||||
const isIOS = useMemo(() => detectIOS(), []);
|
||||
const nativeSupported = useMemo(() => supportsFullscreen(), []);
|
||||
|
||||
const reevaluate = useCallback(() => {
|
||||
if (!isMobileLayout) {
|
||||
setVisible(false);
|
||||
setForceVisible(false);
|
||||
return;
|
||||
}
|
||||
if (isDismissed()) {
|
||||
if (!forceVisible && isDismissed()) {
|
||||
setVisible(false);
|
||||
return;
|
||||
}
|
||||
@@ -79,7 +82,7 @@ export function useFullscreenPrompt(layout) {
|
||||
}
|
||||
setMode('native');
|
||||
setVisible(true);
|
||||
}, [isIOS, isMobileLayout]);
|
||||
}, [forceVisible, isIOS, isMobileLayout]);
|
||||
|
||||
useEffect(() => {
|
||||
reevaluate();
|
||||
@@ -89,6 +92,7 @@ export function useFullscreenPrompt(layout) {
|
||||
if (typeof document === 'undefined') return undefined;
|
||||
const handler = () => {
|
||||
if (document.fullscreenElement) {
|
||||
setForceVisible(false);
|
||||
setVisible(false);
|
||||
return;
|
||||
}
|
||||
@@ -104,12 +108,14 @@ export function useFullscreenPrompt(layout) {
|
||||
|
||||
const dismiss = useCallback(() => {
|
||||
markDismissed();
|
||||
setForceVisible(false);
|
||||
setVisible(false);
|
||||
}, []);
|
||||
|
||||
const enterFullscreen = useCallback(async () => {
|
||||
if (!isMobileLayout || isIOS) return false;
|
||||
if (typeof document === 'undefined') return false;
|
||||
if (document.fullscreenElement) return true;
|
||||
const element = document.documentElement;
|
||||
if (!element) return false;
|
||||
const request =
|
||||
@@ -124,6 +130,7 @@ export function useFullscreenPrompt(layout) {
|
||||
await result;
|
||||
}
|
||||
markDismissed();
|
||||
setForceVisible(false);
|
||||
setVisible(false);
|
||||
return true;
|
||||
} catch (error) {
|
||||
@@ -132,8 +139,16 @@ export function useFullscreenPrompt(layout) {
|
||||
}
|
||||
}, [isIOS, isMobileLayout]);
|
||||
|
||||
const showPrompt = useCallback(() => {
|
||||
if (!isMobileLayout) return;
|
||||
setForceVisible(true);
|
||||
setMode(isIOS ? 'pwa-hint' : 'native');
|
||||
setVisible(true);
|
||||
}, [isIOS, isMobileLayout]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isMobileLayout) {
|
||||
setForceVisible(false);
|
||||
setVisible(false);
|
||||
}
|
||||
}, [isMobileLayout]);
|
||||
@@ -141,8 +156,11 @@ export function useFullscreenPrompt(layout) {
|
||||
return {
|
||||
visible,
|
||||
mode,
|
||||
isIOS,
|
||||
nativeSupported,
|
||||
enterFullscreen,
|
||||
dismiss,
|
||||
showPrompt,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user