Skip to content

Commit b00f923

Browse files
committed
Mantine v8 migration
1 parent 73c0b44 commit b00f923

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+2400
-1198
lines changed

.prettierrc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
tabWidth: 4

package-lock.json

Lines changed: 1580 additions & 469 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
"@types/ua-parser-js": "^0.7.39",
3232
"copy-webpack-plugin": "^13.0.1",
3333
"css-loader": "^7.1.2",
34+
"css-minimizer-webpack-plugin": "^7.0.4",
35+
"cssnano": "^7.1.2",
3436
"eslint": "^9.38.0",
3537
"eslint-config-love": "^120.0.0",
3638
"eslint-plugin-import": "^2.32.0",
@@ -42,6 +44,9 @@
4244
"globals": "^16.4.0",
4345
"html-webpack-plugin": "^5.6.4",
4446
"mini-css-extract-plugin": "^2.9.4",
47+
"postcss": "^8.5.6",
48+
"postcss-loader": "^8.2.0",
49+
"postcss-preset-mantine": "^1.18.0",
4550
"style-loader": "^3.3.4",
4651
"ts-loader": "^9.5.4",
4752
"typescript": "^5.9.3",
@@ -54,12 +59,12 @@
5459
},
5560
"dependencies": {
5661
"@emotion/react": "^11.14.0",
57-
"@mantine/core": "^6.0.2",
58-
"@mantine/dropzone": "^6.0.22",
59-
"@mantine/form": "^6.0.22",
60-
"@mantine/hooks": "^6.0.2",
61-
"@mantine/modals": "^6.0.22",
62-
"@mantine/notifications": "^6.0.22",
62+
"@mantine/core": "^8.3.9",
63+
"@mantine/dropzone": "^8.3.9",
64+
"@mantine/form": "^8.3.9",
65+
"@mantine/hooks": "^8.3.9",
66+
"@mantine/modals": "^8.3.9",
67+
"@mantine/notifications": "^8.3.9",
6368
"@popperjs/core": "^2.11.8",
6469
"@tanstack/react-query": "^4.42.0",
6570
"@tanstack/react-query-devtools": "^4.42.0",

postcss.config.mjs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default {
2+
plugins: {
3+
"postcss-preset-mantine": {},
4+
},
5+
};

src/components/app.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import type { ServerConfig } from "../config";
2121
import React, { useCallback, useContext, useEffect, useMemo, useReducer, useRef, useState } from "react";
2222
import { Server } from "../components/server";
2323
import { ClientManager } from "../clientmanager";
24-
import { ActionIcon, Box, Button, Flex, Menu, Stack, useMantineColorScheme } from "@mantine/core";
24+
import { ActionIcon, Box, Button, Flex, Menu, Stack, useComputedColorScheme } from "@mantine/core";
2525
import { QueryClientProvider } from "@tanstack/react-query";
2626
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
2727
import { queryClient } from "queries";
@@ -35,6 +35,9 @@ import { modKeyString } from "trutil";
3535
import { ColorSchemeToggle, FontSizeToggle, ShowVersion } from "./miscbuttons";
3636
import { AppSettingsModal } from "./modals/settings";
3737
import { ToolbarButton } from "./toolbar";
38+
import "@mantine/core/styles.css";
39+
import "@mantine/notifications/styles.css";
40+
import "css/custom.css";
3841

3942
const { appWindow, invoke, makeCreateTorrentView } = await import(/* webpackChunkName: "taurishim" */"taurishim");
4043

@@ -45,7 +48,7 @@ interface PassEventData {
4548

4649
function CreateTorrentButton() {
4750
const config = useContext(ConfigContext);
48-
const { colorScheme } = useMantineColorScheme();
51+
const colorScheme = useComputedColorScheme();
4952

5053
useEffect(() => {
5154
const unlisten = appWindow.listen<PassEventData>("pass-from-window", ({ payload: data }) => {
@@ -83,7 +86,7 @@ function CreateTorrentButton() {
8386
export function App(props: React.PropsWithChildren) {
8487
return (
8588
<QueryClientProvider client={queryClient}>
86-
<Notifications limit={5} style={{ bottom: "2.5rem" }} />
89+
<Notifications limit={5}/>
8790
{props.children}
8891
<ReactQueryDevtools toggleButtonProps={{ style: { marginBottom: "2rem" } }} />
8992
</QueryClientProvider>
@@ -192,7 +195,7 @@ export default function TauriApp() {
192195
onClick={() => tabsRef.current?.openTab(s.name)}>{s.name}
193196
</Button>;
194197
})}
195-
<Box sx={{ flexGrow: 1 }} />
198+
<Box style={{ flexGrow: 1 }} />
196199
<Button onClick={serverConfigHandlers.open}>
197200
Configure servers
198201
</Button>

src/components/colorchooser.tsx

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* along with this program. If not, see <https://www.gnu.org/licenses/>.
1717
*/
1818

19-
import { ActionIcon, ColorSwatch, Grid, Popover, useMantineTheme } from "@mantine/core";
19+
import { ActionIcon, ColorSwatch, Popover, useMantineTheme, Group, Button } from "@mantine/core";
2020
import type { ColorSetting } from "config";
2121
import React, { useState } from "react";
2222

@@ -30,36 +30,32 @@ const shades = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
3030
export default function ColorChooser(props: ColorChooserProps) {
3131
const theme = useMantineTheme();
3232
const [opened, setOpened] = useState(false);
33-
const swatchOutline = theme.colorScheme === "dark" ? theme.colors.gray[7] : theme.colors.dark[6];
3433

3534
return (
36-
<Popover width="20rem" position="right-start" withArrow withinPortal shadow="md" opened={opened} onChange={setOpened} >
35+
<Popover width="20rem" position="right-start" withArrow transitionProps={{ duration: 0 }} shadow="md" opened={opened} onChange={setOpened} >
3736
<Popover.Target>
38-
<ActionIcon onClick={() => { setOpened((o) => !o); }}>
37+
<ActionIcon variant="subtle" onClick={() => { setOpened((o) => !o); }}>
3938
<ColorSwatch
40-
color={theme.colors[props.value.color][props.value.shade]}
41-
sx={{ border: `1px solid ${swatchOutline}` }} />
39+
color={theme.colors[props.value.color][props.value.shade]} />
4240
</ActionIcon>
4341
</Popover.Target>
4442
<Popover.Dropdown>
45-
<ActionIcon p="lg" onClick={() => {
43+
<Button variant="subtle" p="lg" onClick={() => {
4644
props.onChange(undefined);
4745
setOpened(false);
4846
}}>
4947
Reset
50-
</ActionIcon>
51-
<Grid columns={10}>
52-
{Object.keys(theme.colors).map((color) => shades.map((shade) => (
53-
<Grid.Col key={`${color}:${shade}`} span={1} p="0.1rem">
54-
<ActionIcon onClick={() => {
48+
</Button>
49+
{Object.keys(theme.colors).map((color) =>
50+
<Group key={color} wrap="nowrap" gap="0">
51+
{shades.map((shade) =>
52+
<ActionIcon key={shade} m="0.1rem" variant="subtle" onClick={() => {
5553
props.onChange({ color, shade, computed: theme.colors[color][shade] });
5654
setOpened(false);
5755
}}>
5856
<ColorSwatch color={theme.colors[color][shade]} />
59-
</ActionIcon>
60-
</Grid.Col>
61-
)))}
62-
</Grid>
57+
</ActionIcon>)}
58+
</Group>)}
6359
</Popover.Dropdown>
6460
</Popover>
6561
);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.contextMenuButton {
2+
position: absolute;
3+
width: 0;
4+
height: 0;
5+
padding: 0;
6+
border: 0;
7+
}

src/components/contextmenu.tsx

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@
1616
* along with this program. If not, see <https://www.gnu.org/licenses/>.
1717
*/
1818

19-
import type { MenuProps, PortalProps } from "@mantine/core";
19+
import type { MenuProps } from "@mantine/core";
2020
import { Button, Menu, Portal, ScrollArea } from "@mantine/core";
21-
import React, { useCallback, useEffect, useState } from "react";
21+
import React, { useCallback, useState } from "react";
22+
import classes from "./contextmenu.module.css";
2223

2324
export interface ContextMenuInfo {
2425
x: number,
@@ -40,61 +41,55 @@ export function useContextMenu(): [ContextMenuInfo, React.Dispatch<ContextMenuIn
4041

4142
export interface ContextMenuProps extends MenuProps {
4243
contextMenuInfo: ContextMenuInfo,
43-
containerRef?: PortalProps["innerRef"],
4444
closeOnClickOutside?: boolean,
45+
autosize?: boolean,
4546
setContextMenuInfo: (i: ContextMenuInfo) => void,
4647
}
4748

4849
export function ContextMenu({
4950
contextMenuInfo,
50-
containerRef,
5151
closeOnClickOutside = true,
52+
autosize,
5253
setContextMenuInfo,
5354
children,
5455
...other
5556
}: ContextMenuProps) {
5657
const onClose = useCallback(
57-
() => { setContextMenuInfo({ ...contextMenuInfo, opened: false }); },
58-
[contextMenuInfo, setContextMenuInfo]);
59-
60-
const [opened, setOpened] = useState<boolean>(false);
61-
62-
useEffect(() => { setOpened(contextMenuInfo.opened); }, [contextMenuInfo.opened]);
58+
() => {
59+
setContextMenuInfo({ ...contextMenuInfo, opened: false });
60+
}, [contextMenuInfo, setContextMenuInfo]);
6361

6462
return (
6563
<Menu {...other}
66-
opened={opened}
64+
opened={contextMenuInfo.opened}
6765
onClose={onClose}
6866
offset={0}
6967
middlewares={{ shift: true, flip: true }}
7068
position="right-start"
69+
transitionProps={{ duration: 0 }}
7170
closeOnClickOutside={closeOnClickOutside}
7271
zIndex={500}
7372
>
74-
<Portal innerRef={containerRef}>
73+
<Portal>
7574
<Menu.Target>
7675
<Button unstyled
77-
sx={{
78-
position: "absolute",
79-
width: 0,
80-
height: 0,
81-
padding: 0,
82-
border: 0,
83-
}}
76+
className={classes.contextMenuButton}
8477
style={{
8578
left: contextMenuInfo.x,
8679
top: contextMenuInfo.y,
8780
}} />
8881
</Menu.Target>
8982
<Menu.Dropdown>
90-
<ScrollArea.Autosize
91-
type="auto"
92-
mah="calc(100vh - 0.5rem)"
93-
offsetScrollbars
94-
styles={{ viewport: { paddingBottom: 0 } }}
95-
>
96-
{children}
97-
</ScrollArea.Autosize>
83+
{autosize === true
84+
? <ScrollArea.Autosize
85+
type="auto"
86+
mah="calc(100vh - 0.5rem)"
87+
offsetScrollbars
88+
styles={{ viewport: { paddingBottom: 0 } }}
89+
>
90+
{children}
91+
</ScrollArea.Autosize>
92+
: children}
9893
</Menu.Dropdown>
9994
</Portal>
10095
</Menu>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.textAreaRoot {
2+
flex-grow: 1;
3+
display: flex;
4+
flex-direction: column;
5+
}
6+
7+
.textAreaWrapper {
8+
flex-grow: 1;
9+
}
10+
11+
.textAreaInput {
12+
height: 100%;
13+
}

src/components/createtorrentform.tsx

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616
* along with this program. If not, see <https://www.gnu.org/licenses/>.
1717
*/
1818

19-
import type { Styles, TextInputStylesNames } from "@mantine/core";
2019
import { Box, Button, Checkbox, Flex, Group, Slider, Text, TextInput, Textarea, useMantineColorScheme } from "@mantine/core";
2120
import { useForm } from "@mantine/form";
2221
import React, { useCallback, useEffect, useRef, useState } from "react";
2322
import { appVersion } from "./modals/version";
2423
import { ProgressBar } from "./progressbar";
2524
import { bytesToHumanReadableStr } from "trutil";
25+
import classes from "./createtorrentform.module.css";
2626
const { appWindow, invoke, dialogOpen, dialogSave } = await import(/* webpackChunkName: "taurishim" */"taurishim");
2727

2828
interface FormValues {
@@ -37,18 +37,10 @@ interface FormValues {
3737
version: string,
3838
}
3939

40-
const textAreaStyles: Styles<TextInputStylesNames, Record<string, unknown>> = {
41-
root: {
42-
flexGrow: 1,
43-
display: "flex",
44-
flexDirection: "column",
45-
},
46-
wrapper: {
47-
flexGrow: 1,
48-
},
49-
input: {
50-
height: "100%",
51-
},
40+
const textAreaClassNames = {
41+
root: classes.textAreaRoot,
42+
wrapper: classes.textAreaWrapper,
43+
input: classes.textAreaInput,
5244
};
5345

5446
const byteLabel = (b: number) => {
@@ -85,7 +77,7 @@ interface InfobarState {
8577
}
8678

8779
export default function CreateTorrentForm() {
88-
const { toggleColorScheme } = useMantineColorScheme();
80+
const { setColorScheme } = useMantineColorScheme();
8981
const [defaultTrackers, setDefaultTrackers] = useState<string[]>([]);
9082
const [pieces, setPieces] = useState({
9183
done: 0,
@@ -114,11 +106,11 @@ export default function CreateTorrentForm() {
114106
useEffect(() => {
115107
void appWindow.once<PassEventData>("pass-from-window", ({ payload: data }) => {
116108
const { colorScheme, defaultTrackers } = JSON.parse(data.payload);
117-
toggleColorScheme(colorScheme);
109+
setColorScheme(colorScheme);
118110
setDefaultTrackers(defaultTrackers);
119111
});
120112
void invoke("pass_to_window", { to: "main", payload: "ready" });
121-
}, [toggleColorScheme]);
113+
}, [setColorScheme]);
122114

123115
const { setFieldValue } = form;
124116

@@ -245,12 +237,12 @@ export default function CreateTorrentForm() {
245237
const browseDisabled = ["calculating", "generating"].includes(state.state);
246238

247239
return (
248-
<Flex direction="column" h="100%" w="100%" p="lg" gap="lg">
240+
<Flex direction="column" h="100%" w="100%" p="lg" gap="md">
249241
<Group align="flex-end">
250242
<TextInput
251243
label={"Select file or directory"}
252244
{...form.getInputProps("path")}
253-
styles={{ root: { flexGrow: 1 } }}
245+
style={{ flexGrow: 1 }}
254246
readOnly
255247
autoComplete="off" autoCorrect="off" autoCapitalize="off" spellCheck="false" />
256248
<Button onClick={onBrowseFile} disabled={browseDisabled}>File</Button>
@@ -263,6 +255,7 @@ export default function CreateTorrentForm() {
263255
<Text fz="sm">Piece size</Text>
264256
<Slider
265257
pt="2.5rem"
258+
mt="-0.5rem"
266259
pb="0.5rem"
267260
px="1rem"
268261
scale={(v) => 2 ** v}
@@ -284,21 +277,21 @@ export default function CreateTorrentForm() {
284277
label="Private torrent"
285278
{...form.getInputProps("private", { type: "checkbox" })} />
286279
<Group align="flex-end">
287-
<Box sx={{ flexGrow: 1 }}>Tracker list, one per line, empty line between tiers</Box>
280+
<Box style={{ flexGrow: 1 }}>Tracker list, one per line, empty line between tiers</Box>
288281
<Button onClick={addDefaultTrackers}>Add default list</Button>
289282
</Group>
290283
<Textarea
291-
styles={textAreaStyles}
284+
classNames={textAreaClassNames}
292285
value={form.values.announceList.join("\n")}
293286
onChange={(e) => { form.setFieldValue("announceList", e.target.value.split("\n")); }} />
294287
<Textarea
295-
styles={textAreaStyles}
288+
classNames={textAreaClassNames}
296289
label="Web seed URLs, one per line"
297290
value={form.values.urlList.join("\n")}
298291
onChange={(e) => { form.setFieldValue("urlList", e.target.value.split("\n")); }} />
299292
<Box h="1.5rem">
300293
{state.state === "error" &&
301-
<Text color="red">{state.error}</Text>}
294+
<Text c="red">{state.error}</Text>}
302295
{state.state === "calculating" &&
303296
<Text>Calculating sizes...</Text>}
304297
{state.state === "sizes" &&
@@ -316,7 +309,7 @@ export default function CreateTorrentForm() {
316309
{state.state === "done" &&
317310
<Text>{`Torrent infohash: ${state.hash}`}</Text>}
318311
</Box>
319-
<Group position="center">
312+
<Group justify="center">
320313
{(["idle", "error", "calculating", "sizes"].includes(state.state)) &&
321314
<Button miw="10rem" onClick={onGenerate} disabled={state.state === "calculating"}>Generate</Button>}
322315
{state.state === "generating" &&

0 commit comments

Comments
 (0)