diff --git a/src/components/colorswatch.tsx b/src/components/colorswatch.tsx
new file mode 100644
index 0000000..1aa118f
--- /dev/null
+++ b/src/components/colorswatch.tsx
@@ -0,0 +1,71 @@
+/**
+ * TrguiNG - next gen remote GUI for transmission torrent daemon
+ * Copyright (C) 2023 qu1ck (mail at qu1ck.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+import type { DefaultMantineColor } from "@mantine/core";
+import { ActionIcon, ColorSwatch, Grid, Popover, useMantineTheme } from "@mantine/core";
+import React, { useState } from "react";
+
+export interface ColorSetting {
+ color: DefaultMantineColor,
+ shade: number,
+}
+
+interface ColorChooserProps {
+ value: ColorSetting,
+ onChange: (value: ColorSetting | undefined) => void,
+}
+
+const shades = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+
+export default function ColorChooser(props: ColorChooserProps) {
+ const theme = useMantineTheme();
+ const [opened, setOpened] = useState(false);
+ const swatchOutline = theme.colorScheme === "dark" ? theme.colors.gray[7] : theme.colors.dark[6];
+
+ return (
+
+
+ { setOpened((o) => !o); }}>
+
+
+
+
+ {
+ props.onChange(undefined);
+ setOpened(false);
+ }}>
+ Reset
+
+
+ {Object.keys(theme.colors).map((color) => shades.map((shade) => (
+
+ {
+ props.onChange({ color, shade });
+ setOpened(false);
+ }}>
+
+
+
+ )))}
+
+
+
+ );
+}
diff --git a/src/components/mantinetheme.tsx b/src/components/mantinetheme.tsx
index e9b3ad4..a6c9fbe 100644
--- a/src/components/mantinetheme.tsx
+++ b/src/components/mantinetheme.tsx
@@ -20,7 +20,7 @@ import { ColorSchemeProvider, Global, MantineProvider } from "@mantine/core";
import type { ColorScheme, MantineThemeOverride } from "@mantine/core";
import { useColorScheme } from "@mantine/hooks";
import { ConfigContext } from "config";
-import { FontsizeContextProvider, useFontSize } from "fontsize";
+import { FontsizeContextProvider, GlobalStyleOverridesContextProvider, useFontSize, useGlobalStyleOverrides } from "themehooks";
import React, { useCallback, useContext, useState } from "react";
const Theme: (colorScheme: ColorScheme) => MantineThemeOverride = (colorScheme) => ({
@@ -67,7 +67,7 @@ const Theme: (colorScheme: ColorScheme) => MantineThemeOverride = (colorScheme)
},
},
colors: {
- secondaryColorName: ["#dcfdff", "#b2f4fd", "#85ebf9", "#58e3f6", "#36d9f3", "#25c0d9", "#1696aa", "#066b7a", "#00404a", "#00171b"],
+ turquoise: ["#dcfdff", "#b2f4fd", "#85ebf9", "#58e3f6", "#36d9f3", "#25c0d9", "#1696aa", "#066b7a", "#00404a", "#00171b"],
},
spacing: {
xs: "0.3rem",
@@ -80,12 +80,21 @@ const Theme: (colorScheme: ColorScheme) => MantineThemeOverride = (colorScheme)
function GlobalStyles() {
const fontSize = useFontSize();
+ const styleOverrides = useGlobalStyleOverrides();
return (
({
html: {
fontSize: `${fontSize.value}em`,
},
+ body: {
+ color: styleOverrides.color === undefined
+ ? undefined
+ : theme.colors[styleOverrides.color.color][styleOverrides.color.shade],
+ backgroundColor: styleOverrides.backgroundColor === undefined
+ ? undefined
+ : theme.colors[styleOverrides.backgroundColor.color][styleOverrides.backgroundColor.shade],
+ },
"::-webkit-scrollbar": {
width: "0.75em",
height: "0.75em",
@@ -134,10 +143,12 @@ export default function CustomMantineProvider({ children }: { children: React.Re
return (
-
-
- {children}
-
+
+
+
+ {children}
+
+
);
diff --git a/src/components/miscbuttons.tsx b/src/components/miscbuttons.tsx
index d527333..fb2b3da 100644
--- a/src/components/miscbuttons.tsx
+++ b/src/components/miscbuttons.tsx
@@ -23,7 +23,7 @@ import React from "react";
import { VersionModal } from "components/modals/version";
import { useDisclosure, useHotkeys } from "@mantine/hooks";
import { modKeyString } from "trutil";
-import { useFontSize } from "fontsize";
+import { useFontSize } from "themehooks";
export function ColorSchemeToggle(props: { sz?: string, btn?: MantineNumberSize }) {
const { colorScheme, toggleColorScheme } = useMantineColorScheme();
diff --git a/src/components/modals/interfacepanel.tsx b/src/components/modals/interfacepanel.tsx
index 5341c94..f8b4831 100644
--- a/src/components/modals/interfacepanel.tsx
+++ b/src/components/modals/interfacepanel.tsx
@@ -16,9 +16,12 @@
* along with this program. If not, see .
*/
-import React from "react";
-import { Checkbox, Grid, NumberInput, Textarea } from "@mantine/core";
+import React, { useCallback } from "react";
+import { Checkbox, Grid, NumberInput, Textarea, useMantineTheme } from "@mantine/core";
import type { UseFormReturnType } from "@mantine/form";
+import type { ColorSetting } from "components/colorswatch";
+import ColorChooser from "components/colorswatch";
+import { useGlobalStyleOverrides } from "themehooks";
export interface InterfaceFormValues {
interface: {
@@ -29,8 +32,40 @@ export interface InterfaceFormValues {
}
export function InterfaceSettigsPanel(props: { form: UseFormReturnType }) {
+ const theme = useMantineTheme();
+ const { color, backgroundColor, setStyle } = useGlobalStyleOverrides();
+
+ const setTextColor = useCallback((color: ColorSetting | undefined) => {
+ setStyle({ color, backgroundColor });
+ }, [backgroundColor, setStyle]);
+
+ const setBgColor = useCallback((backgroundColor: ColorSetting | undefined) => {
+ setStyle({ color, backgroundColor });
+ }, [color, setStyle]);
+
+ const defaultColor = theme.colorScheme === "dark"
+ ? { color: "dark", shade: 0 }
+ : { color: "dark", shade: 9 };
+
+ const defaultBg = theme.colorScheme === "dark"
+ ? { color: "dark", shade: 7 }
+ : { color: "gray", shade: 0 };
+
return (
+
+ Text
+
+
+
+
+
+ Bakground
+
+
+
+
+
diff --git a/src/components/tables/common.tsx b/src/components/tables/common.tsx
index daf8534..e27d2fb 100644
--- a/src/components/tables/common.tsx
+++ b/src/components/tables/common.tsx
@@ -36,7 +36,7 @@ import type { DropResult } from "react-beautiful-dnd";
import { DragDropContext, Draggable } from "react-beautiful-dnd";
import { StrictModeDroppable } from "components/strictmodedroppable";
import { eventHasModKey, reorderElements } from "trutil";
-import { useFontSize } from "fontsize";
+import { useFontSize } from "themehooks";
const defaultColumn = {
minSize: 30,
diff --git a/src/config.ts b/src/config.ts
index b5f77d1..6d05e37 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -22,6 +22,7 @@ import type {
} from "@tanstack/react-table";
import type { ColorScheme } from "@mantine/core";
import { deobfuscate, obfuscate } from "trutil";
+import type { ColorSetting } from "components/colorswatch";
const { readConfigText, writeConfigText } = await import(/* webpackChunkName: "taurishim" */"taurishim");
export interface ServerConnection {
@@ -116,6 +117,10 @@ interface Settings {
skipAddDialog: boolean,
numLastSaveDirs: number,
defaultTrackers: string[],
+ styleOverrides: {
+ color?: ColorSetting,
+ backgroundColor?: ColorSetting,
+ },
},
}
@@ -213,6 +218,7 @@ const DefaultSettings: Settings = {
skipAddDialog: false,
numLastSaveDirs: 20,
defaultTrackers: [...DefaultTrackerList],
+ styleOverrides: {},
},
};
diff --git a/src/fontsize.tsx b/src/themehooks.tsx
similarity index 70%
rename from src/fontsize.tsx
rename to src/themehooks.tsx
index 967b8fc..a56d8fb 100644
--- a/src/fontsize.tsx
+++ b/src/themehooks.tsx
@@ -17,8 +17,9 @@
*/
import { useToggle } from "@mantine/hooks";
+import type { ColorSetting } from "components/colorswatch";
import { ConfigContext } from "config";
-import React, { useContext, useEffect, useMemo } from "react";
+import React, { useContext, useEffect, useMemo, useState } from "react";
interface FontsizeContextValue {
value: number,
@@ -67,3 +68,30 @@ export function FontsizeContextProvider(props: React.PropsWithChildren) {
export function useFontSize() {
return useContext(FontsizeContext);
}
+
+interface GlobalStyleOverrides {
+ color?: ColorSetting,
+ backgroundColor?: ColorSetting,
+ setStyle: React.Dispatch>,
+}
+
+const GlobalStyleOverridesContext = React.createContext({ setStyle: () => { } });
+
+export function GlobalStyleOverridesContextProvider(props: React.PropsWithChildren) {
+ const config = useContext(ConfigContext);
+ const [style, setStyle] = useState(config.values.interface.styleOverrides);
+
+ useEffect(() => {
+ config.values.interface.styleOverrides = style;
+ }, [config, style]);
+
+ return (
+
+ {props.children}
+
+ );
+}
+
+export function useGlobalStyleOverrides() {
+ return useContext(GlobalStyleOverridesContext);
+}
diff --git a/src/types/mantine.d.ts b/src/types/mantine.d.ts
index 29f750a..e8e6a02 100644
--- a/src/types/mantine.d.ts
+++ b/src/types/mantine.d.ts
@@ -1,6 +1,6 @@
import type { Tuple, DefaultMantineColor } from "@mantine/core";
-type ExtendedCustomColors = "primaryColorName" | "secondaryColorName" | DefaultMantineColor;
+type ExtendedCustomColors = "primaryColorName" | "turquoise" | DefaultMantineColor;
declare module "@mantine/core" {
export interface MantineThemeColorsOverride {