From 0d47efc126b91b4b508cad5a69e3179d2a655683 Mon Sep 17 00:00:00 2001 From: shm Date: Sun, 24 Nov 2024 04:56:17 +0900 Subject: [PATCH] =?UTF-8?q?Fix:=20=E3=82=A8=E3=83=A9=E3=83=BC=E3=83=8F?= =?UTF-8?q?=E3=83=B3=E3=83=89=E3=83=AA=E3=83=B3=E3=82=B0=E3=82=92=E6=94=B9?= =?UTF-8?q?=E5=96=84=E3=81=97=E3=80=81Tauri=E3=83=80=E3=82=A4=E3=82=A2?= =?UTF-8?q?=E3=83=AD=E3=82=B0=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=97=E3=81=A6?= =?UTF-8?q?=E3=82=A8=E3=83=A9=E3=83=BC=E3=83=A1=E3=83=83=E3=82=BB=E3=83=BC?= =?UTF-8?q?=E3=82=B8=E3=82=92=E8=A1=A8=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/atom/useHardwareInfoAtom.ts | 4 +- src/atom/useSettingsAtom.ts | 7 +++ src/components/charts/ProcessTable.tsx | 9 ++- .../forms/UploadImage/useUploadImageForm.ts | 7 ++- src/hooks/useBgImage.ts | 12 +++- src/hooks/useInputListener.ts | 5 +- src/hooks/useTauriDialog.ts | 62 +++++++++++++++++++ src/i18n/en.json | 11 ++++ src/i18n/ja.json | 11 ++++ 9 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 src/hooks/useTauriDialog.ts diff --git a/src/atom/useHardwareInfoAtom.ts b/src/atom/useHardwareInfoAtom.ts index ecd720f..4b96576 100644 --- a/src/atom/useHardwareInfoAtom.ts +++ b/src/atom/useHardwareInfoAtom.ts @@ -1,3 +1,4 @@ +import { useTauriDialog } from "@/hooks/useTauriDialog"; import { type SysInfo, commands } from "@/rspc/bindings"; import { isError } from "@/types/result"; import { atom, useAtom } from "jotai"; @@ -10,11 +11,12 @@ const hardInfoAtom = atom({ export const useHardwareInfoAtom = () => { const [hardwareInfo, setHardInfo] = useAtom(hardInfoAtom); + const { error } = useTauriDialog(); const init = async () => { const fetchedHardwareInfo = await commands.getHardwareInfo(); - if (isError(fetchedHardwareInfo)) { + error(fetchedHardwareInfo.error); console.error("Failed to fetch hardware info:", fetchedHardwareInfo); return; } diff --git a/src/atom/useSettingsAtom.ts b/src/atom/useSettingsAtom.ts index 1925c4e..7d341fd 100644 --- a/src/atom/useSettingsAtom.ts +++ b/src/atom/useSettingsAtom.ts @@ -1,4 +1,5 @@ import { defaultColorRGB } from "@/consts/chart"; +import { useTauriDialog } from "@/hooks/useTauriDialog"; import { type Result, commands } from "@/rspc/bindings"; import type { ChartDataType } from "@/types/hardwareDataType"; import { isError } from "@/types/result"; @@ -26,6 +27,7 @@ const settingsAtom = atom({ }); export const useSettingsAtom = () => { + const { error } = useTauriDialog(); const mapSettingUpdater: { [K in keyof Omit]: ( value: Settings[K], @@ -46,10 +48,12 @@ export const useSettingsAtom = () => { const [settings, setSettings] = useAtom(settingsAtom); + // biome-ignore lint/correctness/useExhaustiveDependencies: const loadSettings = useCallback(async () => { const setting = await commands.getSettings(); if (isError(setting)) { + error(setting.error); console.error("Failed to fetch settings:", setting.error); return; } @@ -69,6 +73,7 @@ export const useSettingsAtom = () => { const result = await mapSettingUpdater[key](value); if (isError(result)) { + error(result.error); console.error(result.error); setSettings((prev) => ({ ...prev, [key]: previousValue })); } @@ -82,6 +87,7 @@ export const useSettingsAtom = () => { const result = await commands.setDisplayTargets(newTargets); if (isError(result)) { + error(result.error); console.error(result.error); return; } @@ -102,6 +108,7 @@ export const useSettingsAtom = () => { const result = await commands.setLineGraphColor(key, value); if (isError(result)) { + error(result.error); console.error(result.error); return; } diff --git a/src/components/charts/ProcessTable.tsx b/src/components/charts/ProcessTable.tsx index 3cb33c8..384561b 100644 --- a/src/components/charts/ProcessTable.tsx +++ b/src/components/charts/ProcessTable.tsx @@ -1,3 +1,4 @@ +import { useTauriDialog } from "@/hooks/useTauriDialog"; import { type ProcessInfo, commands } from "@/rspc/bindings"; import { CaretDown } from "@phosphor-icons/react"; import { atom, useAtom, useSetAtom } from "jotai"; @@ -10,6 +11,7 @@ const ProcessesTable = ({ defaultItemLength, }: { defaultItemLength: number }) => { const { t } = useTranslation(); + const { error } = useTauriDialog(); const [processes] = useAtom(processesAtom); const setAtom = useSetAtom(processesAtom); const [showAllItem, setShowAllItem] = useState(false); @@ -23,8 +25,9 @@ const ProcessesTable = ({ try { const processesData = await commands.getProcessList(); setAtom(processesData); - } catch (error) { - console.error("Failed to fetch processes:", error); + } catch (err) { + error(err as string); + console.error("Failed to fetch processes:", err); } }; @@ -33,7 +36,7 @@ const ProcessesTable = ({ const interval = setInterval(fetchProcesses, 3000); return () => clearInterval(interval); - }, [setAtom]); + }, [setAtom, error]); const sortedProcesses = [...processes]; if (sortConfig !== null) { diff --git a/src/components/forms/UploadImage/useUploadImageForm.ts b/src/components/forms/UploadImage/useUploadImageForm.ts index 79184c6..a5133ef 100644 --- a/src/components/forms/UploadImage/useUploadImageForm.ts +++ b/src/components/forms/UploadImage/useUploadImageForm.ts @@ -1,4 +1,5 @@ import { useBackgroundImage } from "@/hooks/useBgImage"; +import { useTauriDialog } from "@/hooks/useTauriDialog"; import { zodResolver } from "@hookform/resolvers/zod"; import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; @@ -8,6 +9,7 @@ import { z } from "zod"; // 画像アップロードカスタムフック export const useUploadImage = () => { const { t } = useTranslation(); + const { error } = useTauriDialog(); const [displayUrl, setDisplayUrl] = useState(null); const [fileName, setFilename] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); @@ -37,8 +39,9 @@ export const useUploadImage = () => { try { await saveBackgroundImage(values.picture); form.reset(); - } catch (error) { - console.error("Error saveBackgroundImage:", error); + } catch (err) { + error(err as string); + console.error("Error saveBackgroundImage:", err); } setIsSubmitting(false); diff --git a/src/hooks/useBgImage.ts b/src/hooks/useBgImage.ts index 922d11b..5f35975 100644 --- a/src/hooks/useBgImage.ts +++ b/src/hooks/useBgImage.ts @@ -5,17 +5,20 @@ import { isError, isOk } from "@/types/result"; import type { BackgroundImage } from "@/types/settingsType"; import { atom, useAtom } from "jotai"; import { useCallback, useEffect } from "react"; +import { useTauriDialog } from "./useTauriDialog"; const backgroundImageAtom = atom(null); const uploadedBackgroundImagesAtom = atom>([]); export const useBackgroundImage = () => { + const { error } = useTauriDialog(); const [backgroundImage, setBackgroundImage] = useAtom(backgroundImageAtom); const { initBackgroundImages, backgroundImageList, setBackgroundImageList } = useBackgroundImageList(); const { settings, updateSettingAtom } = useSettingsAtom(); + // biome-ignore lint/correctness/useExhaustiveDependencies: const initBackgroundImage = useCallback(async () => { if (settings.selectedBackgroundImg) { const base64Image = await commands.getBackgroundImage( @@ -25,6 +28,7 @@ export const useBackgroundImage = () => { if (isOk(base64Image)) { setBackgroundImage(`data:image/png;base64,${base64Image.data}`); } else { + error(base64Image.error); console.error("Failed to load background image:", base64Image.error); } } else { @@ -43,6 +47,7 @@ export const useBackgroundImage = () => { const fileId = await commands.saveBackgroundImage(base64Image); if (isError(fileId)) { + error(fileId.error); console.error("Failed to save background image:", fileId.error); return; } @@ -63,8 +68,9 @@ export const useBackgroundImage = () => { (v) => v.fileId !== fileId, ); setBackgroundImageList(newBackgroundImages); - } catch (error) { - console.error("Failed to delete background image:", error); + } catch (err) { + error(err as string); + console.error("Failed to delete background image:", err); } }; @@ -77,6 +83,7 @@ export const useBackgroundImage = () => { }; export const useBackgroundImageList = () => { + const { error } = useTauriDialog(); const [backgroundImageList, setBackgroundImageList] = useAtom( uploadedBackgroundImagesAtom, ); @@ -85,6 +92,7 @@ export const useBackgroundImageList = () => { const uploadedBackgroundImages = await commands.getBackgroundImages(); if (isError(uploadedBackgroundImages)) { + error(uploadedBackgroundImages.error); console.error( "Failed to load background images:", uploadedBackgroundImages.error, diff --git a/src/hooks/useInputListener.ts b/src/hooks/useInputListener.ts index 7587b0d..b781764 100644 --- a/src/hooks/useInputListener.ts +++ b/src/hooks/useInputListener.ts @@ -1,8 +1,10 @@ import { commands } from "@/rspc/bindings"; import { useEffect } from "react"; +import { useTauriDialog } from "./useTauriDialog"; import { useTauriStore } from "./useTauriStore"; export const useKeydown = () => { + const { error } = useTauriDialog(); const [isDecorated, setDecorated] = useTauriStore("window_decorated", false); useEffect(() => { @@ -11,6 +13,7 @@ export const useKeydown = () => { await commands.setDecoration(!isDecorated); await setDecorated(!isDecorated); } catch (e) { + error(e as string); console.error("Failed to toggle window decoration:", e); } }; @@ -23,5 +26,5 @@ export const useKeydown = () => { return () => { window.removeEventListener("keydown", handleKeyDown); }; - }, [isDecorated, setDecorated]); + }, [isDecorated, setDecorated, error]); }; diff --git a/src/hooks/useTauriDialog.ts b/src/hooks/useTauriDialog.ts new file mode 100644 index 0000000..a5cb63d --- /dev/null +++ b/src/hooks/useTauriDialog.ts @@ -0,0 +1,62 @@ +import { + ask as showAsk, + confirm as showConfirm, + message as showMessage, +} from "@tauri-apps/plugin-dialog"; +import { useTranslation } from "react-i18next"; + +type Kind = "info" | "warning" | "error"; +type TitleType = + | "info" + | "confirm" + | "success" + | "warning" + | "error" + | "unexpected"; + +export const useTauriDialog = () => { + const { t } = useTranslation(); + + const ask = async ({ + title, + message, + kind, + }: { title?: TitleType; message: string; kind?: Kind }): Promise => { + return await showAsk(message, { + title: title ? t(`error.title.${title}`) : undefined, + kind, + }); + }; + + const confirm = async ({ + title, + message, + kind, + }: { title?: TitleType; message: string; kind?: Kind }): Promise => { + return await showConfirm(message, { + title: title ? t(`error.title.${title}`) : undefined, + kind, + }); + }; + + const message = async ({ + title, + message, + kind, + }: { title?: TitleType; message: string; kind?: Kind }): Promise => { + return await showMessage(message, { + title: title ? t(`error.title.${title}`) : undefined, + kind, + }); + }; + + const error = async (errorMessage: string) => { + return await message({ + title: "error", + message: errorMessage, + kind: "error", + }); + }; + + return { ask, confirm, message, error }; +}; diff --git a/src/i18n/en.json b/src/i18n/en.json index e5320c8..13c157d 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -69,5 +69,16 @@ "opacity": "Opacity" } } + }, + + "error": { + "title": { + "info": "Info", + "confirm": "Confirm", + "warning": "Warning", + "error": "Error", + "success": "Success", + "unexpected": "Unexpected Error" + } } } diff --git a/src/i18n/ja.json b/src/i18n/ja.json index 7ba32f0..421b713 100644 --- a/src/i18n/ja.json +++ b/src/i18n/ja.json @@ -69,5 +69,16 @@ "opacity": "透過率" } } + }, + + "error": { + "title": { + "info": "情報", + "confirm": "確認", + "warning": "警告", + "error": "エラー", + "success": "成功しました", + "unexpected": "予期せぬエラーが発生しました" + } } }