diff --git a/package.json b/package.json
index add5b12..ceaec78 100644
--- a/package.json
+++ b/package.json
@@ -50,6 +50,7 @@
"@trpc/server": "^10.0.0-proxy-beta.23",
"bullmq": "^2.3.2",
"contrast-color": "^1.0.1",
+ "cookies-next": "^2.1.1",
"cron-parser": "^4.6.0",
"cronstrue": "^2.14.0",
"dayjs": "^1.11.5",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 8b87f45..7fbb340 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -34,6 +34,7 @@ specifiers:
autoprefixer: ^10.4.12
bullmq: ^2.3.2
contrast-color: ^1.0.1
+ cookies-next: ^2.1.1
cron-parser: ^4.6.0
cronstrue: ^2.14.0
dayjs: ^1.11.5
@@ -95,6 +96,7 @@ dependencies:
'@trpc/server': 10.0.0-rc.0
bullmq: 2.4.0
contrast-color: 1.0.1
+ cookies-next: 2.1.1
cron-parser: 4.6.0
cronstrue: 2.14.0
dayjs: 1.11.6
@@ -1288,6 +1290,10 @@ packages:
resolution: {integrity: sha512-tQA3wqkn7zb0dpgSxjtTEShUsWEExOBWOQ3ByiUT3SzrMM5wEa55NnoGI9X3671Tf19vDQbU/Co2dWVniGqBpQ==}
dev: true
+ /@types/cookie/0.4.1:
+ resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==}
+ dev: false
+
/@types/express-serve-static-core/4.17.31:
resolution: {integrity: sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==}
dependencies:
@@ -1332,6 +1338,10 @@ packages:
resolution: {integrity: sha512-Y6S38pFr04yb13qqHf8uk1nHE3lXgQ30WZbv1mLliV9pt0NjvqdWttLcrOYLnXbOafknVYRHZGoMSpR9UwfYow==}
dev: true
+ /@types/node/16.18.3:
+ resolution: {integrity: sha512-jh6m0QUhIRcZpNv7Z/rpN+ZWXOicUUQbSoWks7Htkbb9IjFQj4kzcX/xFCkjstCj5flMsN8FiSvt+q+Tcs4Llg==}
+ dev: false
+
/@types/node/18.11.2:
resolution: {integrity: sha512-BWN3M23gLO2jVG8g/XHIRFWiiV4/GckeFIqbU/C4V3xpoBBWSMk4OZomouN0wCkfQFPqgZikyLr7DOYDysIkkw==}
dev: true
@@ -2212,6 +2222,14 @@ packages:
engines: {node: '>= 0.6'}
dev: false
+ /cookies-next/2.1.1:
+ resolution: {integrity: sha512-AZGZPdL1hU3jCjN2UMJTGhLOYzNUN9Gm+v8BdptYIHUdwz397Et1p+sZRfvAl8pKnnmMdX2Pk9xDRKCGBum6GA==}
+ dependencies:
+ '@types/cookie': 0.4.1
+ '@types/node': 16.18.3
+ cookie: 0.4.2
+ dev: false
+
/copy-anything/3.0.2:
resolution: {integrity: sha512-CzATjGXzUQ0EvuvgOCI6A4BGOo2bcVx8B+eC2nF862iv9fopnPQwlrbACakNCHRIJbCSBj+J/9JeDf60k64MkA==}
engines: {node: '>=12.13'}
diff --git a/src/components/addManga/form.tsx b/src/components/addManga/form.tsx
index 90101e7..bdcd306 100644
--- a/src/components/addManga/form.tsx
+++ b/src/components/addManga/form.tsx
@@ -21,7 +21,7 @@ const useStyles = createStyles((theme) => ({
right: '55px',
width: 'calc(100% - 55px)',
height: '50px',
- background: 'white',
+ background: theme.colorScheme === 'dark' ? theme.colors.dark[7] : theme.white,
},
}));
diff --git a/src/components/addManga/index.tsx b/src/components/addManga/index.tsx
index 31368e6..249f8fb 100644
--- a/src/components/addManga/index.tsx
+++ b/src/components/addManga/index.tsx
@@ -11,7 +11,7 @@ const useStyles = createStyles((theme) => ({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
- backgroundColor: theme.colors.gray[4],
+ backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[4] : theme.colors.gray[4],
cursor: 'pointer',
transition: 'transform 150ms ease, box-shadow 150ms ease',
@@ -21,6 +21,10 @@ const useStyles = createStyles((theme) => ({
boxShadow: theme.shadows.md,
},
},
+
+ plusIcon: {
+ color: theme.colorScheme === 'light' ? theme.colors.dark[4] : theme.colors.gray[4],
+ },
}));
export const useAddMangaModal = () => {
@@ -58,7 +62,7 @@ export function AddManga({ onAdd }: { onAdd: () => void }) {
return (
addMangaModal(onAdd)}>
-
+
);
diff --git a/src/components/addManga/mangaSearchResult.tsx b/src/components/addManga/mangaSearchResult.tsx
index 0d222e8..7fedf71 100644
--- a/src/components/addManga/mangaSearchResult.tsx
+++ b/src/components/addManga/mangaSearchResult.tsx
@@ -1,34 +1,40 @@
-import { createStyles, Image, SimpleGrid, Text, UnstyledButton } from '@mantine/core';
+import { createStyles, Image, ScrollArea, SimpleGrid, Text, UnstyledButton } from '@mantine/core';
import { useUncontrolled } from '@mantine/hooks';
import { useEffect, useState } from 'react';
-const useStyles = createStyles((theme, { checked, disabled }: { checked: boolean; disabled: boolean }) => ({
- button: {
- display: 'flex',
- alignItems: 'center',
- width: '100%',
- transition: 'background-color 150ms ease, border-color 150ms ease',
- border: `1px solid ${
- checked
- ? theme.fn.variant({ variant: 'outline', color: theme.primaryColor }).border
- : theme.colorScheme === 'dark'
- ? theme.colors.dark[8]
- : theme.colors.gray[3]
- }`,
- borderRadius: theme.radius.sm,
- padding: theme.spacing.sm,
- backgroundColor: checked
- ? theme.fn.variant({ variant: 'light', color: theme.primaryColor }).background
- : disabled
- ? theme.colors.gray[3]
- : theme.white,
- },
+const useStyles = createStyles((theme, { checked, disabled }: { checked: boolean; disabled: boolean }) => {
+ let backgroundColor = 'light';
+ if (disabled) {
+ backgroundColor = theme.colorScheme === 'dark' ? theme.colors.dark[4] : theme.colors.gray[4];
+ }
+ if (checked) {
+ backgroundColor = theme.fn.variant({ variant: 'light', color: theme.primaryColor }).background!;
+ }
+ return {
+ button: {
+ display: 'flex',
+ alignItems: 'center',
+ width: '100%',
+ transition: 'background-color 150ms ease, border-color 150ms ease',
+ border: `1px solid ${
+ checked
+ ? theme.fn.variant({ variant: 'outline', color: theme.primaryColor }).border
+ : theme.colorScheme === 'dark'
+ ? theme.colors.dark[8]
+ : theme.colors.gray[3]
+ }`,
+ borderRadius: theme.radius.sm,
+ padding: theme.spacing.sm,
+ backgroundColor,
+ outline: 'none !important',
+ },
- body: {
- flex: 1,
- marginLeft: theme.spacing.md,
- },
-}));
+ body: {
+ flex: 1,
+ marginLeft: theme.spacing.md,
+ },
+ };
+});
interface ImageCheckboxProps {
checked?: boolean;
@@ -115,31 +121,33 @@ export function MangaSearchResult({
}, [items]);
return (
-
- {items.map((m) => (
- {
- if (checked) {
- setSelected(m);
- onSelect(m);
- } else {
- setSelected(undefined);
- onSelect(undefined);
- }
- }}
- />
- ))}
-
+
+
+ {items.map((m) => (
+ {
+ if (checked) {
+ setSelected(m);
+ onSelect(m);
+ } else {
+ setSelected(undefined);
+ onSelect(undefined);
+ }
+ }}
+ />
+ ))}
+
+
);
}
diff --git a/src/components/headerSearch.tsx b/src/components/headerSearch.tsx
index 02aad2e..1cdc515 100644
--- a/src/components/headerSearch.tsx
+++ b/src/components/headerSearch.tsx
@@ -17,6 +17,16 @@ const useStyles = createStyles((theme) => ({
backgroundColor: theme.white,
cursor: 'pointer',
outline: '0 !important',
+
+ '&:hover': {
+ backgroundColor: theme.colors.gray[0],
+ },
+ },
+
+ kbd: {
+ backgroundColor: theme.colors.gray[4],
+ borderColor: theme.colors.gray[4],
+ color: theme.black,
},
}));
@@ -87,7 +97,13 @@ export function SearchControl() {
- Ctrl+P
+
+ Ctrl
+
+ +
+
+ P
+
diff --git a/src/components/madeWith.tsx b/src/components/madeWith.tsx
index 452327b..64df8b2 100644
--- a/src/components/madeWith.tsx
+++ b/src/components/madeWith.tsx
@@ -36,7 +36,7 @@ export function MadeWith({ minimized }: { minimized: boolean }): JSX.Element {
{hearth}
in{' '}
-
+
a.k.a. Turkey} inline position="top-start">
Isekai
diff --git a/src/components/mangaCard.tsx b/src/components/mangaCard.tsx
index b4b7bbf..537c728 100644
--- a/src/components/mangaCard.tsx
+++ b/src/components/mangaCard.tsx
@@ -59,12 +59,14 @@ const useStyles = createStyles((theme, _params, getRef) => ({
},
editButton: {
ref: getRef('editButton'),
+ backgroundColor: theme.white,
+ color: theme.colors.blue[6],
position: 'absolute',
right: 10,
bottom: 10,
display: 'none',
'&:hover': {
- backgroundColor: theme.white,
+ backgroundColor: theme.colors.gray[0],
},
},
title: {
diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx
index b7f692f..f711600 100644
--- a/src/components/navbar.tsx
+++ b/src/components/navbar.tsx
@@ -59,10 +59,10 @@ const useStyles = createStyles((theme) => ({
paddingTop: theme.spacing.xs,
paddingBottom: theme.spacing.xs,
borderRadius: theme.radius.sm,
- color: theme.colors.gray[7],
+ color: theme.colorScheme === 'dark' ? theme.colors.gray[5] : theme.colors.gray[8],
'&:hover': {
- backgroundColor: theme.colors.gray[0],
+ backgroundColor: theme.colorScheme === 'dark' ? theme.colors.gray[9] : theme.colors.gray[0],
},
},
}));
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index a3f37f9..9f66b5f 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -1,14 +1,40 @@
-import { AppShell, MantineProvider } from '@mantine/core';
+import { AppShell, ColorScheme, ColorSchemeProvider, MantineProvider } from '@mantine/core';
+import { useColorScheme, useHotkeys } from '@mantine/hooks';
import { ModalsProvider } from '@mantine/modals';
import { NotificationsProvider } from '@mantine/notifications';
+import { getCookie, setCookie } from 'cookies-next';
import type { AppProps } from 'next/app';
import Head from 'next/head';
+import { useEffect, useState } from 'react';
import { KaizokuHeader } from '../components/header';
import { KaizokuNavbar } from '../components/navbar';
import '../styles/globals.css';
import { trpc } from '../utils/trpc';
-function MyApp({ Component, pageProps }: AppProps) {
+function MyApp(props: AppProps) {
+ const { Component, pageProps } = props;
+ const preferredColorScheme = useColorScheme();
+ const [colorScheme, setColorScheme] = useState('light');
+ useEffect(() => {
+ let followSystem = getCookie('follow-system');
+ if (followSystem === undefined) {
+ followSystem = true;
+ setCookie('follow-system', '1');
+ }
+ if (followSystem === '1') {
+ setColorScheme(preferredColorScheme);
+ } else {
+ setColorScheme((getCookie('mantine-color-scheme') as ColorScheme) || preferredColorScheme);
+ }
+ }, [preferredColorScheme]);
+ const toggleColorScheme = (value?: ColorScheme) => {
+ const nextColorScheme = value || (colorScheme === 'dark' ? 'light' : 'dark');
+ setColorScheme(nextColorScheme);
+ setCookie('mantine-color-scheme', nextColorScheme, { maxAge: 60 * 60 * 24 * 30 });
+ };
+
+ useHotkeys([['shift+t', () => toggleColorScheme()]]);
+
return (
<>
@@ -16,29 +42,31 @@ function MyApp({ Component, pageProps }: AppProps) {
-
-
-
- }
- header={}
- styles={(theme) => ({
- main: { backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[8] : theme.colors.gray[0] },
- })}
- >
-
-
-
-
-
+
+
+
+
+ }
+ header={}
+ styles={(theme) => ({
+ main: { backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[8] : theme.colors.gray[0] },
+ })}
+ >
+
+
+
+
+
+
>
);
}