Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

445 electron通用设置中增加回收站加密文件夹设置 #447

Merged
Merged
1 change: 1 addition & 0 deletions apps/electron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"dependencies": {
"@electron-toolkit/preload": "^2.0.0",
"@electron-toolkit/utils": "^1.0.2",
"@heroicons/react": "^2.0.18",
"@rao-pics/api": "workspace:^",
"@rao-pics/constant": "workspace:^",
"@rao-pics/db": "workspace:*",
Expand Down
19 changes: 0 additions & 19 deletions apps/electron/src/renderer/src/components/Svg.tsx

This file was deleted.

4 changes: 4 additions & 0 deletions apps/electron/src/renderer/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
.card-row > div {
@apply flex items-center;
}

.card-row .right-svg {
@apply ml-1 h-4 w-4 text-base-content/30;
}
}

/* windows 窗口透明 */
Expand Down
6 changes: 3 additions & 3 deletions apps/electron/src/renderer/src/pages/basic/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState } from "react";
import { ChevronRightIcon } from "@heroicons/react/24/outline";
import Content from "@renderer/components/Content";
import { ArrowRightSvg } from "@renderer/components/Svg";
import Title from "@renderer/components/Title";
import { useLanguage } from "@renderer/hooks";
import { trpc } from "@renderer/utils/trpc";
Expand Down Expand Up @@ -141,7 +141,7 @@ const BasicPage = () => {
}}
>
<span>{library?.path}</span>
<ArrowRightSvg />
<ChevronRightIcon className="right-svg" />
</span>
</div>

Expand Down Expand Up @@ -234,7 +234,7 @@ const BasicPage = () => {
{config && (
<span>{`http://${config.ip}:${config.clientPort}`}</span>
)}
<ArrowRightSvg />
<ChevronRightIcon className="right-svg" />
</span>
</div>
</div>
Expand Down
3 changes: 3 additions & 0 deletions apps/electron/src/renderer/src/pages/setting/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.custom-select {
@apply select select-xs w-full rounded bg-base-100/50 text-right text-sm font-normal transition-all duration-300 hover:bg-base-100 hover:shadow focus:outline-none;
}
94 changes: 79 additions & 15 deletions apps/electron/src/renderer/src/pages/setting/index.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,58 @@
import {
FolderMinusIcon,
LanguageIcon,
TrashIcon,
} from "@heroicons/react/24/outline";
import Content from "@renderer/components/Content";
import Title from "@renderer/components/Title";
import { useLanguage } from "@renderer/hooks";
import { trpc } from "@renderer/utils/trpc";

import { LANGUAGE } from "@rao-pics/constant";

import "./index.css";

const languages = {
"zh-cn": {
title: "通用",
language_title: "语言",
language_desc: "选择语言",
trash: "回收站素材",
pwd_folder: "加密文件夹素材",
show: "显示",
hide: "不显示",
},
"en-us": {
title: "General",
language_title: "Language",
language_desc: "Select language",
trash: "Trash Material",
pwd_folder: "Password Folder Material",
show: "Show",
hide: "Hide",
},
"zh-tw": {
title: "通用",
language_title: "語言",
language_desc: "選擇語言",
trash: "回收站素材",
pwd_folder: "加密文件夾素材",
show: "顯示",
hide: "不顯示",
},
};

const SettingPage = () => {
const utils = trpc.useContext();

const configUpsert = trpc.config.upsert.useMutation({
onSuccess() {
void utils.config.invalidate();
},
});

const { data: config } = trpc.config.findUnique.useQuery();

const { lang, language, setLanguage } =
useLanguage<typeof languages>(languages);

Expand All @@ -37,20 +67,7 @@ const SettingPage = () => {
<div className="card-wrapper">
<div className="card-row">
<div>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="h-5 w-5"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M10.5 21l5.25-11.25L21 21m-9-3h7.5M3 5.621a48.474 48.474 0 016-.371m0 0c1.12 0 2.233.038 3.334.114M9 5.25V3m3.334 2.364C11.176 10.658 7.69 15.08 3 17.502m9.334-12.138c.896.061 1.785.147 2.666.257m-4.589 8.495a18.023 18.023 0 01-3.827-5.802"
/>
</svg>
<LanguageIcon className="h-5 w-5" />
<span className="ml-2">{lang.language_title}</span>
</div>

Expand All @@ -64,7 +81,7 @@ const SettingPage = () => {
}
}}
value={language}
className="select select-xs w-full bg-transparent text-right text-sm font-normal focus:outline-none"
className="custom-select"
>
{items.map((item) => (
<option key={item.value} value={item.value}>
Expand All @@ -75,6 +92,53 @@ const SettingPage = () => {
</div>
</div>
</div>

<div className="card-wrapper mt-4">
<div className="card-row">
<div>
<TrashIcon className="h-5 w-5" />

<span className="ml-2">{lang.trash}</span>
</div>

<div>
<select
className="custom-select"
value={config?.trash ? 1 : 0}
onChange={(e) => {
configUpsert.mutate({
trash: Number(e.target.value) === 1,
});
}}
>
<option value={0}>{lang.hide}</option>
<option value={1}>{lang.show}</option>
</select>
</div>
</div>

<div className="card-row">
<div>
<FolderMinusIcon className="h-5 w-5" />
<span className="ml-2">{lang.pwd_folder}</span>
</div>

<div>
<select
className="custom-select"
value={config?.pwdFolder ? 1 : 0}
onChange={(e) => {
configUpsert.mutate({
pwdFolder: Number(e.target.value) === 1,
});
}}
>
<option value={0}>{lang.hide}</option>
<option value={1}>{lang.show}</option>
</select>
</div>
</div>
</div>
</div>
</Content>
);
Expand Down
4 changes: 2 additions & 2 deletions apps/electron/src/renderer/src/pages/unsync.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState } from "react";
import { ChevronRightIcon } from "@heroicons/react/24/outline";
import Content from "@renderer/components/Content";
import { ArrowRightSvg } from "@renderer/components/Svg";
import Title from "@renderer/components/Title";
import { useDebounce, useLanguage } from "@renderer/hooks";
import { trpc } from "@renderer/utils/trpc";
Expand Down Expand Up @@ -75,7 +75,7 @@ const UnsyncPage = () => {
.replace(libPath, "")
.replace("/metadata.json", "")}
</span>
<ArrowRightSvg />
<ChevronRightIcon className="right-svg" />
</span>
</div>
</div>
Expand Down
23 changes: 21 additions & 2 deletions packages/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { color } from "./src/color";
import { config } from "./src/config";
import { folder } from "./src/folder";
import { config, configCore } from "./src/config";
import { folder, folderCore } from "./src/folder";
import { image } from "./src/image";
import { library } from "./src/library";
import { log } from "./src/log";
Expand All @@ -21,6 +21,25 @@ export const router = t.router({
log,
});

export const routerCore = {
config: configCore,
folder: folderCore,
};

export type AppRouter = typeof router;
export { t } from "./src/utils";
export * from "./src/express";

let caller: ReturnType<typeof router.createCaller>;

/**
* router.createCaller()
* @returns
*/
export const getCaller = () => {
if (!caller) {
caller = router.createCaller({});
}

return caller;
};
4 changes: 2 additions & 2 deletions packages/api/mocks/folder.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
"children": [],
"modificationTime": 1693138821077,
"tags": [],
"password": "",
"passwordTips": ""
"password": "1234",
"passwordTips": "1234"
}
],
"modificationTime": 1690869001589,
Expand Down
84 changes: 48 additions & 36 deletions packages/api/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,56 @@ import { z } from "zod";
import { DEFAULT_THEME } from "@rao-pics/constant";
import { prisma } from "@rao-pics/db";

import { folderCore } from "./folder";
import { t } from "./utils";

export const configInput = {
upsert: z.object({
language: z.enum(["zh-cn", "en-us", "zh-tw"]).optional(),
theme: z.string().optional(),
color: z.string().optional(),
serverPort: z.number().optional(),
clientPort: z.number().optional(),
ip: z.string().optional(),
pwdFolder: z.boolean().optional(),
trash: z.boolean().optional(),
}),
};

export const configCore = {
findUnique: async () =>
await prisma.config.findFirst({ where: { name: "config" } }),

// pwdFolder 更新逻辑
// 1. config.pwdFolder = true
// 2. 修改 folder.password != null 的 folder.show = true
// 2.1 如果修改的是父级 folder, 则需要同步修改子级 folder
// 3. 查询 Folder 时,只需要返回 folder.show = true 的 folder
upsert: async (input: z.infer<typeof configInput.upsert>) => {
const { pwdFolder } = input;

if (pwdFolder != undefined) {
await folderCore.setPwdFolderShow(pwdFolder);
}

return await prisma.config.upsert({
where: { name: "config" },
update: input,
create: {
...input,
name: "config",
language: input.language ?? "zh-cn",
color: input.color ?? "light",
theme: input.theme ?? DEFAULT_THEME,
},
});
},
};

export const config = t.router({
upsert: t.procedure
.input(
z.object({
language: z.enum(["zh-cn", "en-us", "zh-tw"]).optional(),
theme: z.string().optional(),
color: z.string().optional(),
serverPort: z.number().optional(),
clientPort: z.number().optional(),
ip: z.string().optional(),
}),
)
.mutation(async ({ input }) => {
return await prisma.config.upsert({
where: { name: "config" },
update: {
language: input.language ?? undefined,
color: input.color ?? undefined,
theme: input.theme ?? undefined,
ip: input.ip ?? undefined,
serverPort: input.serverPort ?? undefined,
clientPort: input.clientPort ?? undefined,
},
create: {
name: "config",
language: input.language ?? "zh-cn",
color: input.color ?? "light",
theme: input.theme ?? DEFAULT_THEME,
ip: input.ip,
serverPort: input.serverPort,
clientPort: input.clientPort,
},
});
}),

findUnique: t.procedure.query(async () => {
return await prisma.config.findFirst({ where: { name: "config" } });
}),
.input(configInput.upsert)
.mutation(({ input }) => configCore.upsert(input)),

findUnique: t.procedure.query(configCore.findUnique),
});
Loading