All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
- Introduced a new MacOSTrafficLights component to manage window controls (close, minimize, fullscreen) with custom SVG icons. - Updated DashboardWindowButtons to integrate the new traffic light controls for macOS. - Enhanced window control functionality in mainWindow.js to toggle fullscreen mode. - Added CSS styles for traffic light indicators to improve visual representation. - Refactored DashboardNavigation to streamline the handling of fullscreen state.
213 lines
6.0 KiB
JavaScript
213 lines
6.0 KiB
JavaScript
import { useContext, useEffect, useState } from 'react'
|
|
import PropTypes from 'prop-types'
|
|
import { Flex } from 'antd'
|
|
import { ElectronContext } from '../context/ElectronContext'
|
|
|
|
import CloseColored from '../../../../assets/trafficlights/closecolored.svg?react'
|
|
import CloseHoverColored from '../../../../assets/trafficlights/closehovercolored.svg?react'
|
|
import CloseDownColored from '../../../../assets/trafficlights/closedowncolored.svg?react'
|
|
import MinimizeColored from '../../../../assets/trafficlights/minimizecolored.svg?react'
|
|
import MinimizeHoverColored from '../../../../assets/trafficlights/minimizehovercolored.svg?react'
|
|
import MinimizeDownColored from '../../../../assets/trafficlights/minimizedowncolored.svg?react'
|
|
import FullscreenColored from '../../../../assets/trafficlights/fullscreencolored.svg?react'
|
|
import FullscreenHoverColored from '../../../../assets/trafficlights/fullscreenhovercolored.svg?react'
|
|
import FullscreenDownColored from '../../../../assets/trafficlights/fullscreendowncolored.svg?react'
|
|
import ExitFullscreenHoverColored from '../../../../assets/trafficlights/exitfullscreenhovercolored.svg?react'
|
|
import ExitFullscreenDownColored from '../../../../assets/trafficlights/exitfullscreendowncolored.svg?react'
|
|
import NoFocus from '../../../../assets/trafficlights/nofocus.svg?react'
|
|
|
|
const TRAFFIC_LIGHT_SIZE = 12
|
|
|
|
const TRAFFIC_LIGHT_BUTTON_STYLE = {
|
|
width: TRAFFIC_LIGHT_SIZE,
|
|
height: TRAFFIC_LIGHT_SIZE,
|
|
padding: 0,
|
|
border: 'none',
|
|
background: 'transparent',
|
|
cursor: 'default',
|
|
lineHeight: 0,
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center'
|
|
}
|
|
|
|
const TRAFFIC_LIGHT_ICON_STYLE = {
|
|
width: TRAFFIC_LIGHT_SIZE,
|
|
height: TRAFFIC_LIGHT_SIZE,
|
|
display: 'block'
|
|
}
|
|
|
|
function getTrafficLightIcon({ isEnabled, isFocused, isActive, isHovered, icons }) {
|
|
if (!isEnabled || !isFocused) {
|
|
return icons.noFocus
|
|
}
|
|
if (isActive) {
|
|
return icons.down
|
|
}
|
|
if (isHovered) {
|
|
return icons.hover
|
|
}
|
|
return icons.colored
|
|
}
|
|
|
|
const TrafficLightButton = ({
|
|
action,
|
|
icons,
|
|
isGroupHovered,
|
|
activeAction,
|
|
isEnabled,
|
|
isWindowFocused,
|
|
onActive,
|
|
onAction
|
|
}) => {
|
|
const Icon = getTrafficLightIcon({
|
|
isEnabled,
|
|
isFocused: isWindowFocused,
|
|
isActive: activeAction === action,
|
|
isHovered: isGroupHovered,
|
|
icons
|
|
})
|
|
|
|
const handleMouseDown = (event) => {
|
|
if (!isEnabled) return
|
|
|
|
event.preventDefault()
|
|
event.stopPropagation()
|
|
onActive(action)
|
|
onAction(action)
|
|
}
|
|
|
|
return (
|
|
<button
|
|
type='button'
|
|
aria-label={action}
|
|
aria-disabled={!isEnabled}
|
|
disabled={!isEnabled}
|
|
className='electrobun-webkit-app-region-no-drag'
|
|
style={TRAFFIC_LIGHT_BUTTON_STYLE}
|
|
onMouseDown={handleMouseDown}
|
|
onMouseUp={isEnabled ? () => onActive(null) : undefined}
|
|
>
|
|
<Icon style={TRAFFIC_LIGHT_ICON_STYLE} />
|
|
</button>
|
|
)
|
|
}
|
|
|
|
TrafficLightButton.propTypes = {
|
|
action: PropTypes.string.isRequired,
|
|
icons: PropTypes.shape({
|
|
colored: PropTypes.elementType.isRequired,
|
|
hover: PropTypes.elementType.isRequired,
|
|
down: PropTypes.elementType.isRequired,
|
|
noFocus: PropTypes.elementType.isRequired
|
|
}).isRequired,
|
|
isGroupHovered: PropTypes.bool.isRequired,
|
|
activeAction: PropTypes.string,
|
|
isEnabled: PropTypes.bool.isRequired,
|
|
isWindowFocused: PropTypes.bool.isRequired,
|
|
onActive: PropTypes.func.isRequired,
|
|
onAction: PropTypes.func.isRequired
|
|
}
|
|
|
|
const MacOSTrafficLights = () => {
|
|
const { handleWindowControl, isFullScreen } = useContext(ElectronContext)
|
|
const [isGroupHovered, setIsGroupHovered] = useState(false)
|
|
const [activeAction, setActiveAction] = useState(null)
|
|
const [isWindowFocused, setIsWindowFocused] = useState(
|
|
() => document.hasFocus?.() ?? true
|
|
)
|
|
|
|
useEffect(() => {
|
|
const handleFocus = () => setIsWindowFocused(true)
|
|
const handleBlur = () => setIsWindowFocused(false)
|
|
|
|
window.addEventListener('focus', handleFocus)
|
|
window.addEventListener('blur', handleBlur)
|
|
|
|
return () => {
|
|
window.removeEventListener('focus', handleFocus)
|
|
window.removeEventListener('blur', handleBlur)
|
|
}
|
|
}, [])
|
|
|
|
const fullscreenIcons = isFullScreen
|
|
? {
|
|
colored: FullscreenColored,
|
|
hover: ExitFullscreenHoverColored,
|
|
down: ExitFullscreenDownColored,
|
|
noFocus: NoFocus
|
|
}
|
|
: {
|
|
colored: FullscreenColored,
|
|
hover: FullscreenHoverColored,
|
|
down: FullscreenDownColored,
|
|
noFocus: NoFocus
|
|
}
|
|
|
|
const handleAction = (action) => {
|
|
handleWindowControl(action)
|
|
}
|
|
|
|
return (
|
|
<Flex
|
|
className='electrobun-webkit-app-region-no-drag'
|
|
style={{
|
|
width: '56.6px',
|
|
marginLeft: '12.5px',
|
|
marginRight: '12.5px',
|
|
position: 'relative',
|
|
zIndex: 9999
|
|
}}
|
|
gap={8}
|
|
onMouseEnter={() => setIsGroupHovered(true)}
|
|
onMouseLeave={() => {
|
|
setIsGroupHovered(false)
|
|
setActiveAction(null)
|
|
}}
|
|
>
|
|
<TrafficLightButton
|
|
action='close'
|
|
icons={{
|
|
colored: CloseColored,
|
|
hover: CloseHoverColored,
|
|
down: CloseDownColored,
|
|
noFocus: NoFocus
|
|
}}
|
|
isGroupHovered={isGroupHovered}
|
|
activeAction={activeAction}
|
|
isEnabled
|
|
isWindowFocused={isWindowFocused}
|
|
onActive={setActiveAction}
|
|
onAction={handleAction}
|
|
/>
|
|
<TrafficLightButton
|
|
action='minimize'
|
|
icons={{
|
|
colored: MinimizeColored,
|
|
hover: MinimizeHoverColored,
|
|
down: MinimizeDownColored,
|
|
noFocus: NoFocus
|
|
}}
|
|
isGroupHovered={isGroupHovered}
|
|
activeAction={activeAction}
|
|
isEnabled={!isFullScreen}
|
|
isWindowFocused={isWindowFocused}
|
|
onActive={setActiveAction}
|
|
onAction={handleAction}
|
|
/>
|
|
<TrafficLightButton
|
|
action='fullscreen'
|
|
icons={fullscreenIcons}
|
|
isGroupHovered={isGroupHovered}
|
|
activeAction={activeAction}
|
|
isEnabled
|
|
isWindowFocused={isWindowFocused}
|
|
onActive={setActiveAction}
|
|
onAction={handleAction}
|
|
/>
|
|
</Flex>
|
|
)
|
|
}
|
|
|
|
export default MacOSTrafficLights
|