diff options
Diffstat (limited to 'packages/renderer/src')
-rw-r--r-- | packages/renderer/src/components/ServiceIcon.tsx | 80 | ||||
-rw-r--r-- | packages/renderer/src/components/ServiceSwitcher.tsx | 13 | ||||
-rw-r--r-- | packages/renderer/src/components/Sidebar.tsx | 2 |
3 files changed, 81 insertions, 14 deletions
diff --git a/packages/renderer/src/components/ServiceIcon.tsx b/packages/renderer/src/components/ServiceIcon.tsx index e02da71..83b2a5f 100644 --- a/packages/renderer/src/components/ServiceIcon.tsx +++ b/packages/renderer/src/components/ServiceIcon.tsx | |||
@@ -18,15 +18,18 @@ | |||
18 | * SPDX-License-Identifier: AGPL-3.0-only | 18 | * SPDX-License-Identifier: AGPL-3.0-only |
19 | */ | 19 | */ |
20 | 20 | ||
21 | import { styled } from '@mui/material/styles'; | 21 | import Badge from '@mui/material/Badge'; |
22 | import { styled, useTheme } from '@mui/material/styles'; | ||
23 | import { Service } from '@sophie/shared'; | ||
24 | import { observer } from 'mobx-react-lite'; | ||
22 | import React from 'react'; | 25 | import React from 'react'; |
23 | 26 | ||
24 | const ServiceIconRoot = styled('div', { | 27 | const ServiceIconRoot = styled('div', { |
25 | name: 'ServiceIcon', | 28 | name: 'ServiceIcon', |
26 | slot: 'Root', | 29 | slot: 'Root', |
27 | })(({ theme }) => ({ | 30 | })(({ theme }) => ({ |
28 | width: 34, | 31 | width: 36, |
29 | height: 34, | 32 | height: 36, |
30 | borderRadius: theme.shape.borderRadius, | 33 | borderRadius: theme.shape.borderRadius, |
31 | background: 'currentColor', | 34 | background: 'currentColor', |
32 | display: 'flex', | 35 | display: 'flex', |
@@ -44,10 +47,73 @@ const ServiceIconText = styled('div', { | |||
44 | color: theme.palette.primary.contrastText, | 47 | color: theme.palette.primary.contrastText, |
45 | })); | 48 | })); |
46 | 49 | ||
47 | export default function ServiceIcon({ name }: { name: string }): JSX.Element { | 50 | const IndirectMessageBadge = styled(Badge)(({ theme }) => ({ |
51 | '& .MuiBadge-dot': { | ||
52 | // The indirect message badge floats ouside the icon in the middle. | ||
53 | top: '50%', | ||
54 | ...(theme.direction === 'ltr' | ||
55 | ? { | ||
56 | left: theme.spacing(-1), | ||
57 | } | ||
58 | : { | ||
59 | right: theme.spacing(-1), | ||
60 | }), | ||
61 | background: | ||
62 | theme.palette.mode === 'dark' | ||
63 | ? theme.palette.text.primary | ||
64 | : 'currentColor', | ||
65 | }, | ||
66 | })); | ||
67 | |||
68 | const DirectMessageBadge = styled(Badge)(({ theme }) => ({ | ||
69 | '& .MuiBadge-badge': { | ||
70 | // Move the badge closer to the icon so that even "99+" messages can fit in the sidebar. | ||
71 | ...(theme.direction === 'ltr' | ||
72 | ? { | ||
73 | right: theme.spacing(0.25), | ||
74 | } | ||
75 | : { | ||
76 | left: theme.spacing(0.25), | ||
77 | }), | ||
78 | top: theme.spacing(0.25), | ||
79 | // Set the badge apart from the icon with a shadow (a border would be too heavy). | ||
80 | boxShadow: theme.shadows[1], | ||
81 | // Add a bit more emphasis to the badge. | ||
82 | fontWeight: 700, | ||
83 | }, | ||
84 | })); | ||
85 | |||
86 | function ServiceIcon({ service }: { service: Service }): JSX.Element { | ||
87 | const { direction } = useTheme(); | ||
88 | const { | ||
89 | settings: { name }, | ||
90 | directMessageCount, | ||
91 | indirectMessageCount, | ||
92 | } = service; | ||
93 | |||
48 | return ( | 94 | return ( |
49 | <ServiceIconRoot> | 95 | <IndirectMessageBadge |
50 | <ServiceIconText>{name.length > 0 ? name[0] : '?'}</ServiceIconText> | 96 | badgeContent={indirectMessageCount} |
51 | </ServiceIconRoot> | 97 | variant="dot" |
98 | anchorOrigin={{ | ||
99 | vertical: 'top', | ||
100 | horizontal: direction === 'ltr' ? 'left' : 'right', | ||
101 | }} | ||
102 | > | ||
103 | <DirectMessageBadge | ||
104 | badgeContent={directMessageCount} | ||
105 | color="error" | ||
106 | anchorOrigin={{ | ||
107 | vertical: 'top', | ||
108 | horizontal: direction === 'ltr' ? 'right' : 'left', | ||
109 | }} | ||
110 | > | ||
111 | <ServiceIconRoot> | ||
112 | <ServiceIconText>{name.length > 0 ? name[0] : '?'}</ServiceIconText> | ||
113 | </ServiceIconRoot> | ||
114 | </DirectMessageBadge> | ||
115 | </IndirectMessageBadge> | ||
52 | ); | 116 | ); |
53 | } | 117 | } |
118 | |||
119 | export default observer(ServiceIcon); | ||
diff --git a/packages/renderer/src/components/ServiceSwitcher.tsx b/packages/renderer/src/components/ServiceSwitcher.tsx index e4d371e..2cf997e 100644 --- a/packages/renderer/src/components/ServiceSwitcher.tsx +++ b/packages/renderer/src/components/ServiceSwitcher.tsx | |||
@@ -32,7 +32,6 @@ const ServiceSwitcherRoot = styled(Tabs, { | |||
32 | slot: 'Root', | 32 | slot: 'Root', |
33 | })(({ theme }) => ({ | 33 | })(({ theme }) => ({ |
34 | '.MuiTabs-indicator': { | 34 | '.MuiTabs-indicator': { |
35 | width: 3, | ||
36 | ...(theme.direction === 'ltr' | 35 | ...(theme.direction === 'ltr' |
37 | ? { | 36 | ? { |
38 | left: 0, | 37 | left: 0, |
@@ -56,12 +55,12 @@ const ServiceSwitcherTab = styled(Tab, { | |||
56 | '&.Mui-selected': { | 55 | '&.Mui-selected': { |
57 | backgroundColor: | 56 | backgroundColor: |
58 | theme.palette.mode === 'dark' | 57 | theme.palette.mode === 'dark' |
59 | ? alpha(theme.palette.text.primary, 0.16) | 58 | ? alpha(theme.palette.text.primary, 0.12) |
60 | : alpha(theme.palette.primary.light, 0.3), | 59 | : alpha(theme.palette.primary.light, 0.24), |
61 | }, | 60 | }, |
62 | })); | 61 | })); |
63 | 62 | ||
64 | export default observer(() => { | 63 | function ServiceSwitcher(): JSX.Element { |
65 | const store = useStore(); | 64 | const store = useStore(); |
66 | const { | 65 | const { |
67 | settings: { selectedService }, | 66 | settings: { selectedService }, |
@@ -81,10 +80,12 @@ export default observer(() => { | |||
81 | <ServiceSwitcherTab | 80 | <ServiceSwitcherTab |
82 | key={service.id} | 81 | key={service.id} |
83 | value={service.id} | 82 | value={service.id} |
84 | icon={<ServiceIcon name={service.settings.name} />} | 83 | icon={<ServiceIcon service={service} />} |
85 | aria-label={service.settings.name} | 84 | aria-label={service.settings.name} |
86 | /> | 85 | /> |
87 | ))} | 86 | ))} |
88 | </ServiceSwitcherRoot> | 87 | </ServiceSwitcherRoot> |
89 | ); | 88 | ); |
90 | }); | 89 | } |
90 | |||
91 | export default observer(ServiceSwitcher); | ||
diff --git a/packages/renderer/src/components/Sidebar.tsx b/packages/renderer/src/components/Sidebar.tsx index ed78fc6..0eb8f93 100644 --- a/packages/renderer/src/components/Sidebar.tsx +++ b/packages/renderer/src/components/Sidebar.tsx | |||
@@ -39,7 +39,7 @@ export default function Sidebar(): JSX.Element { | |||
39 | backgroundClip: 'padding-box', | 39 | backgroundClip: 'padding-box', |
40 | background: alpha(theme.palette.text.primary, 0.09), | 40 | background: alpha(theme.palette.text.primary, 0.09), |
41 | borderInlineEnd: `1px solid ${theme.palette.divider}`, | 41 | borderInlineEnd: `1px solid ${theme.palette.divider}`, |
42 | minWidth: 67, | 42 | minWidth: 69, |
43 | })} | 43 | })} |
44 | > | 44 | > |
45 | <ServiceSwitcher /> | 45 | <ServiceSwitcher /> |