diff options
author | Kristóf Marussy <kristof@marussy.com> | 2022-01-04 16:29:39 +0100 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2022-02-08 21:42:25 +0100 |
commit | 2d26e9f2ea26f9cc89e9aac8c09e132a5311f6a5 (patch) | |
tree | 1faab6e1af7ce89a2c797589a5aeea8d14b06496 /packages/renderer/src/components | |
parent | fix: Make sure the BrowserView has integer coords (diff) | |
download | sophie-2d26e9f2ea26f9cc89e9aac8c09e132a5311f6a5.tar.gz sophie-2d26e9f2ea26f9cc89e9aac8c09e132a5311f6a5.tar.zst sophie-2d26e9f2ea26f9cc89e9aac8c09e132a5311f6a5.zip |
feat: Service switcher buttons
Currently, they do nothing.
Signed-off-by: Kristóf Marussy <kristof@marussy.com>
Diffstat (limited to 'packages/renderer/src/components')
-rw-r--r-- | packages/renderer/src/components/ServiceIcon.tsx | 53 | ||||
-rw-r--r-- | packages/renderer/src/components/ServiceSwitcher.tsx | 88 | ||||
-rw-r--r-- | packages/renderer/src/components/Sidebar.tsx | 13 |
3 files changed, 151 insertions, 3 deletions
diff --git a/packages/renderer/src/components/ServiceIcon.tsx b/packages/renderer/src/components/ServiceIcon.tsx new file mode 100644 index 0000000..e02da71 --- /dev/null +++ b/packages/renderer/src/components/ServiceIcon.tsx | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2022 Kristóf Marussy <kristof@marussy.com> | ||
3 | * | ||
4 | * This file is part of Sophie. | ||
5 | * | ||
6 | * Sophie is free software: you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU Affero General Public License as | ||
8 | * published by the Free Software Foundation, version 3. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU Affero General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Affero General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | * | ||
18 | * SPDX-License-Identifier: AGPL-3.0-only | ||
19 | */ | ||
20 | |||
21 | import { styled } from '@mui/material/styles'; | ||
22 | import React from 'react'; | ||
23 | |||
24 | const ServiceIconRoot = styled('div', { | ||
25 | name: 'ServiceIcon', | ||
26 | slot: 'Root', | ||
27 | })(({ theme }) => ({ | ||
28 | width: 34, | ||
29 | height: 34, | ||
30 | borderRadius: theme.shape.borderRadius, | ||
31 | background: 'currentColor', | ||
32 | display: 'flex', | ||
33 | justifyContent: 'center', | ||
34 | alignItems: 'center', | ||
35 | })); | ||
36 | |||
37 | const ServiceIconText = styled('div', { | ||
38 | name: 'ServiceIcon', | ||
39 | slot: 'Text', | ||
40 | })(({ theme }) => ({ | ||
41 | display: 'inline-block', | ||
42 | flex: 0, | ||
43 | fontSize: theme.typography.pxToRem(24), | ||
44 | color: theme.palette.primary.contrastText, | ||
45 | })); | ||
46 | |||
47 | export default function ServiceIcon({ name }: { name: string }): JSX.Element { | ||
48 | return ( | ||
49 | <ServiceIconRoot> | ||
50 | <ServiceIconText>{name.length > 0 ? name[0] : '?'}</ServiceIconText> | ||
51 | </ServiceIconRoot> | ||
52 | ); | ||
53 | } | ||
diff --git a/packages/renderer/src/components/ServiceSwitcher.tsx b/packages/renderer/src/components/ServiceSwitcher.tsx new file mode 100644 index 0000000..b454451 --- /dev/null +++ b/packages/renderer/src/components/ServiceSwitcher.tsx | |||
@@ -0,0 +1,88 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2022 Kristóf Marussy <kristof@marussy.com> | ||
3 | * | ||
4 | * This file is part of Sophie. | ||
5 | * | ||
6 | * Sophie is free software: you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU Affero General Public License as | ||
8 | * published by the Free Software Foundation, version 3. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU Affero General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Affero General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | * | ||
18 | * SPDX-License-Identifier: AGPL-3.0-only | ||
19 | */ | ||
20 | |||
21 | import Tab from '@mui/material/Tab'; | ||
22 | import Tabs from '@mui/material/Tabs'; | ||
23 | import { alpha, styled } from '@mui/material/styles'; | ||
24 | import { observer } from 'mobx-react-lite'; | ||
25 | import React, { useState } from 'react'; | ||
26 | |||
27 | import ServiceIcon from './ServiceIcon'; | ||
28 | import { useStore } from './StoreProvider'; | ||
29 | |||
30 | const ServiceSwitcherRoot = styled(Tabs, { | ||
31 | name: 'ServiceSwitcher', | ||
32 | slot: 'Root', | ||
33 | })(({ theme }) => ({ | ||
34 | '.MuiTabs-indicator': { | ||
35 | width: 3, | ||
36 | ...(theme.direction === 'ltr' | ||
37 | ? { | ||
38 | left: 0, | ||
39 | right: 'auto', | ||
40 | } | ||
41 | : { | ||
42 | left: 'auto', | ||
43 | right: 0, | ||
44 | }), | ||
45 | }, | ||
46 | })); | ||
47 | |||
48 | const ServiceSwitcherTab = styled(Tab, { | ||
49 | name: 'ServiceSwitcher', | ||
50 | slot: 'Tab', | ||
51 | })(({ theme }) => ({ | ||
52 | minWidth: 0, | ||
53 | transition: theme.transitions.create('background-color', { | ||
54 | duration: theme.transitions.duration.shortest, | ||
55 | }), | ||
56 | '&.Mui-selected': { | ||
57 | backgroundColor: | ||
58 | theme.palette.mode === 'dark' | ||
59 | ? alpha(theme.palette.text.primary, 0.16) | ||
60 | : alpha(theme.palette.primary.light, 0.3), | ||
61 | }, | ||
62 | })); | ||
63 | |||
64 | export default observer(() => { | ||
65 | const { services } = useStore(); | ||
66 | // TODO Move this to the `SharedStore`. | ||
67 | const [selectedService, setSelectedService] = useState<string | boolean>( | ||
68 | false, | ||
69 | ); | ||
70 | |||
71 | return ( | ||
72 | <ServiceSwitcherRoot | ||
73 | variant="scrollable" | ||
74 | orientation="vertical" | ||
75 | value={selectedService} | ||
76 | onChange={(_event, newValue: string) => setSelectedService(newValue)} | ||
77 | > | ||
78 | {services.map((service) => ( | ||
79 | <ServiceSwitcherTab | ||
80 | key={service.id} | ||
81 | value={service.id} | ||
82 | icon={<ServiceIcon name={service.name} />} | ||
83 | aria-label={service.name} | ||
84 | /> | ||
85 | ))} | ||
86 | </ServiceSwitcherRoot> | ||
87 | ); | ||
88 | }); | ||
diff --git a/packages/renderer/src/components/Sidebar.tsx b/packages/renderer/src/components/Sidebar.tsx index 44a47b0..ed78fc6 100644 --- a/packages/renderer/src/components/Sidebar.tsx +++ b/packages/renderer/src/components/Sidebar.tsx | |||
@@ -19,23 +19,30 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | import Box from '@mui/material/Box'; | 21 | import Box from '@mui/material/Box'; |
22 | import { alpha } from '@mui/material/styles'; | ||
22 | import React from 'react'; | 23 | import React from 'react'; |
23 | 24 | ||
25 | import ServiceSwitcher from './ServiceSwitcher'; | ||
24 | import ToggleDarkModeButton from './ToggleDarkModeButton'; | 26 | import ToggleDarkModeButton from './ToggleDarkModeButton'; |
25 | 27 | ||
26 | export default function Sidebar(): JSX.Element { | 28 | export default function Sidebar(): JSX.Element { |
27 | return ( | 29 | return ( |
28 | <Box | 30 | <Box |
31 | component="aside" | ||
29 | sx={(theme) => ({ | 32 | sx={(theme) => ({ |
30 | background: theme.palette.divider, | ||
31 | flex: 0, | 33 | flex: 0, |
32 | display: 'flex', | 34 | display: 'flex', |
33 | flexDirection: 'column', | 35 | flexDirection: 'column', |
34 | alignItems: 'center', | 36 | alignItems: 'center', |
35 | justifyContent: 'flex-end', | 37 | justifyContent: 'space-between', |
36 | padding: 1, | 38 | paddingBottom: 1, |
39 | backgroundClip: 'padding-box', | ||
40 | background: alpha(theme.palette.text.primary, 0.09), | ||
41 | borderInlineEnd: `1px solid ${theme.palette.divider}`, | ||
42 | minWidth: 67, | ||
37 | })} | 43 | })} |
38 | > | 44 | > |
45 | <ServiceSwitcher /> | ||
39 | <ToggleDarkModeButton /> | 46 | <ToggleDarkModeButton /> |
40 | </Box> | 47 | </Box> |
41 | ); | 48 | ); |