From 1743621c3c2b0474be81276390fa45399105a4af Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Mon, 14 Mar 2022 20:06:52 +0100 Subject: feat(renderer): Show service error on service icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Service icons fade out on errors and an icon is displayed. Signed-off-by: Kristóf Marussy --- .../src/components/sidebar/ServiceIcon.tsx | 71 ++++++++++++++++------ 1 file changed, 52 insertions(+), 19 deletions(-) diff --git a/packages/renderer/src/components/sidebar/ServiceIcon.tsx b/packages/renderer/src/components/sidebar/ServiceIcon.tsx index fe047cf..b8f9b96 100644 --- a/packages/renderer/src/components/sidebar/ServiceIcon.tsx +++ b/packages/renderer/src/components/sidebar/ServiceIcon.tsx @@ -18,6 +18,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import IconWarning from '@mui/icons-material/Warning'; import Badge from '@mui/material/Badge'; import { styled, useTheme } from '@mui/material/styles'; import { observer } from 'mobx-react-lite'; @@ -28,7 +29,8 @@ import type Service from '../../stores/Service'; const ServiceIconRoot = styled('div', { name: 'ServiceIcon', slot: 'Root', -})(({ theme }) => ({ + shouldForwardProp: (prop) => prop !== 'hasError', +})<{ hasError: boolean }>(({ theme, hasError }) => ({ width: 36, height: 36, borderRadius: theme.shape.borderRadius, @@ -36,6 +38,13 @@ const ServiceIconRoot = styled('div', { display: 'flex', justifyContent: 'center', alignItems: 'center', + filter: hasError ? 'grayscale(100%)' : 'none', + opacity: hasError ? theme.palette.action.disabledOpacity : 1, + transition: theme.transitions.create(['filter', 'opacity'], { + duration: hasError + ? theme.transitions.duration.enteringScreen + : theme.transitions.duration.leavingScreen, + }), })); const ServiceIconText = styled('div', { @@ -48,15 +57,18 @@ const ServiceIconText = styled('div', { color: theme.palette.primary.contrastText, })); -const ServiceIconBadge = styled(Badge, { - name: 'ServiceIcon', - slot: 'Badge', -})(({ theme }) => ({ - '.MuiBadge-badge': { +const ServiceIconBadgeBase = styled(Badge)({ + '& > .MuiBadge-badge': { // Place badge above the sidebar inner shadow. zIndex: 200, }, - '.MuiBadge-dot': { +}); + +const ServiceIconBadge = styled(ServiceIconBadgeBase, { + name: 'ServiceIcon', + slot: 'Badge', +})(({ theme }) => ({ + '& > .MuiBadge-dot': { background: theme.palette.mode === 'dark' ? theme.palette.text.primary @@ -64,15 +76,28 @@ const ServiceIconBadge = styled(Badge, { }, })); +const ServiceIconErrorBadge = styled(ServiceIconBadgeBase, { + name: 'ServiceIcon', + slot: 'ErrorBadge', +})(({ theme }) => ({ + '& > .MuiBadge-standard': { + color: + theme.palette.mode === 'dark' + ? theme.palette.error.light + : theme.palette.error.main, + }, +})); + function ServiceIcon({ service }: { service: Service }): JSX.Element { const { direction } = useTheme(); const { settings: { name }, directMessageCount, indirectMessageCount, + hasError, } = service; - // Hadge color histeresis for smooth appear / disappear animation. + // Badge color histeresis for smooth appear / disappear animation. // If we compute hasDirectMessage = directMessageCount >= 1 directly (without any histeresis), // the badge momentarily turns light during the disappear animation. const [hasDirectMessage, setHasDirectMessage] = useState(false); @@ -85,21 +110,29 @@ function ServiceIcon({ service }: { service: Service }): JSX.Element { }, [directMessageCount, indirectMessageCount, setHasDirectMessage]); return ( - : 0} anchorOrigin={{ - vertical: 'top', + vertical: 'bottom', horizontal: direction === 'ltr' ? 'right' : 'left', }} > - - {name.length > 0 ? name[0] : '?'} - - + + + {name.length > 0 ? name[0] : '?'} + + + ); } -- cgit v1.2.3-54-g00ecf