mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-16 15:32:15 -07:00
auto lint fixes
This commit is contained in:
parent
9f85845973
commit
9b6c806c00
5 changed files with 42 additions and 40 deletions
|
|
@ -50,22 +50,22 @@ export const RefreshGuardModal: React.FC<RefreshGuardModalProps> = ({
|
||||||
{title}
|
{title}
|
||||||
</Box>
|
</Box>
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
|
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<Alert severity="warning" sx={{ mb: 2 }}>
|
<Alert severity="warning" sx={{ mb: 2 }}>
|
||||||
<Typography variant="body1" id="refresh-guard-description">
|
<Typography variant="body1" id="refresh-guard-description">
|
||||||
{message}
|
{message}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Alert>
|
</Alert>
|
||||||
|
|
||||||
<Typography variant="body2" color="textSecondary">
|
<Typography variant="body2" color="textSecondary">
|
||||||
Your browser may also show a confirmation dialog. Both dialogs are asking the same thing -
|
Your browser may also show a confirmation dialog. Both dialogs are asking the same thing -
|
||||||
whether you want to leave the page and lose your current progress.
|
whether you want to leave the page and lose your current progress.
|
||||||
</Typography>
|
</Typography>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button
|
<Button
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
|
@ -73,7 +73,7 @@ export const RefreshGuardModal: React.FC<RefreshGuardModalProps> = ({
|
||||||
>
|
>
|
||||||
{cancelButtonText}
|
{cancelButtonText}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={onConfirm}
|
onClick={onConfirm}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
color="error"
|
color="error"
|
||||||
|
|
@ -83,4 +83,4 @@ export const RefreshGuardModal: React.FC<RefreshGuardModalProps> = ({
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from 'react';
|
||||||
import { useGameGuard } from "hooks";
|
import { useGameGuard } from 'hooks';
|
||||||
import { RefreshGuardModal } from "../RefreshGuardModal/RefreshGuardModal";
|
import { RefreshGuardModal } from '../RefreshGuardModal/RefreshGuardModal';
|
||||||
|
|
||||||
interface RefreshGuardProviderProps {
|
interface RefreshGuardProviderProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
|
|
@ -34,8 +34,8 @@ export const RefreshGuardProvider: React.FC<RefreshGuardProviderProps> = ({
|
||||||
onClose={handleCancelNavigation}
|
onClose={handleCancelNavigation}
|
||||||
onConfirm={handleConfirmNavigation}
|
onConfirm={handleConfirmNavigation}
|
||||||
message={navigationMessage}
|
message={navigationMessage}
|
||||||
title={isInActiveGame ? "Active Game Warning" : "Connection Warning"}
|
title={isInActiveGame ? 'Active Game Warning' : 'Connection Warning'}
|
||||||
confirmButtonText={isInActiveGame ? "Leave Game" : "Leave Anyway"}
|
confirmButtonText={isInActiveGame ? 'Leave Game' : 'Leave Anyway'}
|
||||||
cancelButtonText="Stay"
|
cancelButtonText="Stay"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
@ -45,7 +45,7 @@ export const RefreshGuardProvider: React.FC<RefreshGuardProviderProps> = ({
|
||||||
onClose={handleCancelRefresh}
|
onClose={handleCancelRefresh}
|
||||||
onConfirm={handleConfirmRefresh}
|
onConfirm={handleConfirmRefresh}
|
||||||
message={refreshMessage}
|
message={refreshMessage}
|
||||||
title={isInActiveGame ? "Page Refresh Warning" : "Connection Warning"}
|
title={isInActiveGame ? 'Page Refresh Warning' : 'Connection Warning'}
|
||||||
confirmButtonText="Refresh Anyway"
|
confirmButtonText="Refresh Anyway"
|
||||||
cancelButtonText="Stay on Page"
|
cancelButtonText="Stay on Page"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,14 @@ interface UseGameGuardReturn {
|
||||||
handleConfirmNavigation: () => void;
|
handleConfirmNavigation: () => void;
|
||||||
handleCancelNavigation: () => void;
|
handleCancelNavigation: () => void;
|
||||||
navigationMessage: string;
|
navigationMessage: string;
|
||||||
|
|
||||||
// Refresh guard (browser refresh)
|
// Refresh guard (browser refresh)
|
||||||
showRefreshModal: boolean;
|
showRefreshModal: boolean;
|
||||||
setShowRefreshModal: (show: boolean) => void;
|
setShowRefreshModal: (show: boolean) => void;
|
||||||
handleConfirmRefresh: () => void;
|
handleConfirmRefresh: () => void;
|
||||||
handleCancelRefresh: () => void;
|
handleCancelRefresh: () => void;
|
||||||
refreshMessage: string;
|
refreshMessage: string;
|
||||||
|
|
||||||
// Guard state
|
// Guard state
|
||||||
isInActiveGame: boolean;
|
isInActiveGame: boolean;
|
||||||
isConnected: boolean;
|
isConnected: boolean;
|
||||||
|
|
@ -30,7 +30,7 @@ interface UseGameGuardReturn {
|
||||||
/**
|
/**
|
||||||
* Combined hook that guards against page refresh (browser dialog) and SPA navigation (custom modal)
|
* Combined hook that guards against page refresh (browser dialog) and SPA navigation (custom modal)
|
||||||
* when user is in an active game or has an active connection.
|
* when user is in an active game or has an active connection.
|
||||||
*
|
*
|
||||||
* - Browser refresh/navigation: Shows native browser dialog only
|
* - Browser refresh/navigation: Shows native browser dialog only
|
||||||
* - SPA navigation: Shows custom modal with detailed warning
|
* - SPA navigation: Shows custom modal with detailed warning
|
||||||
*/
|
*/
|
||||||
|
|
@ -39,17 +39,17 @@ export const useGameGuard = (): UseGameGuardReturn => {
|
||||||
const connectionStatus = useSelector(ServerSelectors.getState);
|
const connectionStatus = useSelector(ServerSelectors.getState);
|
||||||
const joinedGameIds = useSelector(RoomsSelectors.getJoinedGameIds);
|
const joinedGameIds = useSelector(RoomsSelectors.getJoinedGameIds);
|
||||||
const joinedRoomIds = useSelector(RoomsSelectors.getJoinedRoomIds);
|
const joinedRoomIds = useSelector(RoomsSelectors.getJoinedRoomIds);
|
||||||
|
|
||||||
// Determine if user is in an active state that should be guarded
|
// Determine if user is in an active state that should be guarded
|
||||||
const isConnected = connectionStatus === StatusEnum.LOGGED_IN;
|
const isConnected = connectionStatus === StatusEnum.LOGGED_IN;
|
||||||
const isInActiveGame = Object.values(joinedGameIds).some(roomGames =>
|
const isInActiveGame = Object.values(joinedGameIds).some(roomGames =>
|
||||||
Object.keys(roomGames).length > 0
|
Object.keys(roomGames).length > 0
|
||||||
);
|
);
|
||||||
const isInRoom = Object.keys(joinedRoomIds).length > 0;
|
const isInRoom = Object.keys(joinedRoomIds).length > 0;
|
||||||
|
|
||||||
// Guard conditions
|
// Guard conditions
|
||||||
const shouldGuard = isConnected && (isInActiveGame || isInRoom);
|
const shouldGuard = isConnected && (isInActiveGame || isInRoom);
|
||||||
|
|
||||||
// Messages based on current state
|
// Messages based on current state
|
||||||
const getMessage = (): string => {
|
const getMessage = (): string => {
|
||||||
if (isInActiveGame) {
|
if (isInActiveGame) {
|
||||||
|
|
@ -72,7 +72,7 @@ export const useGameGuard = (): UseGameGuardReturn => {
|
||||||
// Note: Specific game leave commands would be implemented here
|
// Note: Specific game leave commands would be implemented here
|
||||||
// For now, we'll just disconnect the WebSocket
|
// For now, we'll just disconnect the WebSocket
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disconnect from server
|
// Disconnect from server
|
||||||
webClient.disconnect();
|
webClient.disconnect();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -109,7 +109,7 @@ export const useGameGuard = (): UseGameGuardReturn => {
|
||||||
},
|
},
|
||||||
handleCancelNavigation: navigationGuard.handleCancelNavigation,
|
handleCancelNavigation: navigationGuard.handleCancelNavigation,
|
||||||
navigationMessage: navigationGuard.guardMessage,
|
navigationMessage: navigationGuard.guardMessage,
|
||||||
|
|
||||||
// Refresh guard (browser refresh)
|
// Refresh guard (browser refresh)
|
||||||
showRefreshModal: refreshGuard.showModal,
|
showRefreshModal: refreshGuard.showModal,
|
||||||
setShowRefreshModal: refreshGuard.setShowModal,
|
setShowRefreshModal: refreshGuard.setShowModal,
|
||||||
|
|
@ -121,10 +121,10 @@ export const useGameGuard = (): UseGameGuardReturn => {
|
||||||
refreshGuard.setShowModal(false);
|
refreshGuard.setShowModal(false);
|
||||||
},
|
},
|
||||||
refreshMessage: refreshGuard.guardMessage,
|
refreshMessage: refreshGuard.guardMessage,
|
||||||
|
|
||||||
// State
|
// State
|
||||||
isInActiveGame,
|
isInActiveGame,
|
||||||
isConnected,
|
isConnected,
|
||||||
shouldGuard
|
shouldGuard
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ interface UseNavigationGuardReturn {
|
||||||
/**
|
/**
|
||||||
* Hook to guard against navigation within the SPA when user has unsaved changes.
|
* Hook to guard against navigation within the SPA when user has unsaved changes.
|
||||||
* Works with React Router to block navigation and show confirmation dialog.
|
* Works with React Router to block navigation and show confirmation dialog.
|
||||||
*
|
*
|
||||||
* @param options Configuration for the navigation guard
|
* @param options Configuration for the navigation guard
|
||||||
* @returns Modal state controls and navigation handlers
|
* @returns Modal state controls and navigation handlers
|
||||||
*/
|
*/
|
||||||
|
|
@ -30,11 +30,11 @@ export const useNavigationGuard = ({
|
||||||
}: UseNavigationGuardOptions): UseNavigationGuardReturn => {
|
}: UseNavigationGuardOptions): UseNavigationGuardReturn => {
|
||||||
const [showModal, setShowModal] = useState(false);
|
const [showModal, setShowModal] = useState(false);
|
||||||
const [pendingLocation, setPendingLocation] = useState<string | null>(null);
|
const [pendingLocation, setPendingLocation] = useState<string | null>(null);
|
||||||
|
|
||||||
// Safely get React Router hooks - they might not be available
|
// Safely get React Router hooks - they might not be available
|
||||||
let navigate: ReturnType<typeof useNavigate> | null = null;
|
let navigate: ReturnType<typeof useNavigate> | null = null;
|
||||||
let location: ReturnType<typeof useLocation> | null = null;
|
let location: ReturnType<typeof useLocation> | null = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
navigate = useNavigate();
|
navigate = useNavigate();
|
||||||
location = useLocation();
|
location = useLocation();
|
||||||
|
|
@ -64,9 +64,11 @@ export const useNavigationGuard = ({
|
||||||
const handleLinkClick = (event: Event) => {
|
const handleLinkClick = (event: Event) => {
|
||||||
const target = event.target as HTMLElement;
|
const target = event.target as HTMLElement;
|
||||||
const link = target.closest('a');
|
const link = target.closest('a');
|
||||||
|
|
||||||
if (!link) return;
|
if (!link) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const href = link.getAttribute('href');
|
const href = link.getAttribute('href');
|
||||||
if (!href || href.startsWith('#') || href.startsWith('http') || href.startsWith('mailto:')) {
|
if (!href || href.startsWith('#') || href.startsWith('http') || href.startsWith('mailto:')) {
|
||||||
return; // Allow external links, anchors, and mailto links
|
return; // Allow external links, anchors, and mailto links
|
||||||
|
|
@ -75,11 +77,11 @@ export const useNavigationGuard = ({
|
||||||
// Check if this is a React Router navigation
|
// Check if this is a React Router navigation
|
||||||
if (href !== location.pathname) {
|
if (href !== location.pathname) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
if (onBeforeNavigate) {
|
if (onBeforeNavigate) {
|
||||||
onBeforeNavigate(href);
|
onBeforeNavigate(href);
|
||||||
}
|
}
|
||||||
|
|
||||||
setPendingLocation(href);
|
setPendingLocation(href);
|
||||||
setShowModal(true);
|
setShowModal(true);
|
||||||
}
|
}
|
||||||
|
|
@ -89,15 +91,15 @@ export const useNavigationGuard = ({
|
||||||
if (shouldGuard) {
|
if (shouldGuard) {
|
||||||
// Browser back/forward button pressed
|
// Browser back/forward button pressed
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
const targetPath = window.location.pathname;
|
const targetPath = window.location.pathname;
|
||||||
if (onBeforeNavigate) {
|
if (onBeforeNavigate) {
|
||||||
onBeforeNavigate(targetPath);
|
onBeforeNavigate(targetPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
setPendingLocation(targetPath);
|
setPendingLocation(targetPath);
|
||||||
setShowModal(true);
|
setShowModal(true);
|
||||||
|
|
||||||
// Restore current URL in history
|
// Restore current URL in history
|
||||||
window.history.pushState(null, '', location.pathname);
|
window.history.pushState(null, '', location.pathname);
|
||||||
}
|
}
|
||||||
|
|
@ -129,4 +131,4 @@ export const useNavigationGuard = ({
|
||||||
handleCancelNavigation,
|
handleCancelNavigation,
|
||||||
guardMessage: message
|
guardMessage: message
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ interface UseRefreshGuardReturn {
|
||||||
/**
|
/**
|
||||||
* Hook to guard against accidental page refresh or navigation away from the site.
|
* Hook to guard against accidental page refresh or navigation away from the site.
|
||||||
* Shows both browser's native beforeunload dialog and a custom modal for better UX.
|
* Shows both browser's native beforeunload dialog and a custom modal for better UX.
|
||||||
*
|
*
|
||||||
* @param options Configuration for the refresh guard
|
* @param options Configuration for the refresh guard
|
||||||
* @returns Modal state controls and current guard message
|
* @returns Modal state controls and current guard message
|
||||||
*/
|
*/
|
||||||
|
|
@ -35,7 +35,7 @@ export const useRefreshGuard = ({
|
||||||
// Show browser's native dialog first
|
// Show browser's native dialog first
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.returnValue = ''; // Required for Chrome
|
event.returnValue = ''; // Required for Chrome
|
||||||
|
|
||||||
// Schedule custom modal to show after browser dialog is dismissed
|
// Schedule custom modal to show after browser dialog is dismissed
|
||||||
// This only happens if user chooses "Stay" on the browser dialog
|
// This only happens if user chooses "Stay" on the browser dialog
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
@ -43,7 +43,7 @@ export const useRefreshGuard = ({
|
||||||
setShowModal(true);
|
setShowModal(true);
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
return ''; // Required for other browsers
|
return ''; // Required for other browsers
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -78,4 +78,4 @@ export const useRefreshGuard = ({
|
||||||
setShowModal,
|
setShowModal,
|
||||||
guardMessage: message
|
guardMessage: message
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue