diff --git a/.lingma/rules/project_rule.md b/.lingma/rules/project_rule.md new file mode 100644 index 0000000..4ce458c --- /dev/null +++ b/.lingma/rules/project_rule.md @@ -0,0 +1,2 @@ +**添加规则文件可帮助模型精准理解你的编码偏好,如框架、代码风格等** +**规则文件只对当前工程生效,单文件限制10000字符。如果无需将该文件提交到远程 Git 仓库,请将其添加到 .gitignore** diff --git a/bun.lockb b/bun.lockb index 0a8b540..9eefc28 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index e6c19f6..829ac03 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "@types/throttle-debounce": "^5.0.2", "framer-motion": "^12.5.0", "jotai": "^2.12.2", - "next": "15.2.0", + "next": "15.2.2", "next-themes": "^0.4.6", "react": "^19.0.0", "react-dom": "^19.0.0", @@ -65,7 +65,7 @@ "eslint": "9.14.0", "eslint-config-next": "15.0.3", "husky": "^9.1.7", - "lint-staged": "^15.4.3", + "lint-staged": "^15.5.0", "postcss": "^8.5.3", "postcss-import": "^16.1.0", "postcss-nesting": "^13.0.1", diff --git a/src/app/(main)/preference/general/page.tsx b/src/app/(main)/preference/general/page.tsx index 8f7bc65..d5cb9ef 100644 --- a/src/app/(main)/preference/general/page.tsx +++ b/src/app/(main)/preference/general/page.tsx @@ -1,18 +1,16 @@ "use client" -import { appStore } from "@/store/app" -import { useSnapshot } from "valtio" +import { useAppStore } from "@/store/app" export default function Page() { - void appStore.start() - const app = useSnapshot(appStore.state) + const app = useAppStore() return (
-

版本号:{app.version}

-

是否有更新:{app.hasUpdate ? "有" : "无"}

-

初始化:{app.inited ? "是" : "否"}

-

公告:{app.notice}

-

是否使用镜像源:{app.useMirror ? "是" : "否"}

+

版本号:{app.state.version}

+

是否有更新:{app.state.hasUpdate ? "有" : "无"}

+

初始化:{app.state.inited ? "是" : "否"}

+

公告:{app.state.notice}

+

是否使用镜像源:{app.state.useMirror ? "是" : "否"}

) } diff --git a/src/app/(main)/preference/path/page.tsx b/src/app/(main)/preference/path/page.tsx index 3af57bb..299a1dc 100644 --- a/src/app/(main)/preference/path/page.tsx +++ b/src/app/(main)/preference/path/page.tsx @@ -1,18 +1,16 @@ "use client" -import { currentUser, steamStore } from "@/store/steam" -import { useSnapshot } from "valtio" +import { useSteamStore } from "@/store/steam" export default function Page() { - void steamStore.start() - const steam = useSnapshot(steamStore.state) + const steam = useSteamStore() return (
-

Steam路径:{steam.dir}

-

游戏路径:{steam.csDir}

-

Steam路径有效:{steam.isDirValid ? "是" : "否"}

-

游戏路径有效:{steam.isCsDirValid ? "是" : "否"}

-

Steam账号:{currentUser().accountName}

+

Steam路径:{steam.state.dir}

+

游戏路径:{steam.state.csDir}

+

Steam路径有效:{steam.state.isDirValid ? "是" : "否"}

+

游戏路径有效:{steam.state.isCsDirValid ? "是" : "否"}

+

Steam账号:{steam.currentUser().accountName}

) } diff --git a/src/app/prepare/page.tsx b/src/app/prepare/page.tsx index 9e7767b..85844ca 100644 --- a/src/app/prepare/page.tsx +++ b/src/app/prepare/page.tsx @@ -1,18 +1,16 @@ "use client" -import { currentUser, setCsDir, setDir, steamStore } from "@/store/steam" +import { useSteamStore } from "@/store/steam" import { useEffect, useState } from "react" -import { useSnapshot } from "valtio" export default function Page() { - void steamStore.start() - const steam = useSnapshot(steamStore.state) - const [steamDir, setSteamDir] = useState(steam.dir) - const [cs2Dir, setCs2Dir] = useState(steam.csDir) + const steam = useSteamStore() + const [steamDir, setSteamDir] = useState(steam.state.dir) + const [cs2Dir, setCs2Dir] = useState(steam.state.csDir) useEffect(() => { - setSteamDir(steam.dir) - setCs2Dir(steam.csDir) - }, [steam.dir, steam.csDir]) + setSteamDir(steam.state.dir) + setCs2Dir(steam.state.csDir) + }, [steam.state.dir, steam.state.csDir]) return (
{ setSteamDir(e.target.value) - setDir(e.target.value) + steam.setDir(e.target.value) }} />

CS2所在文件夹

@@ -38,10 +36,10 @@ export default function Page() { value={cs2Dir} onChange={(e) => { setCs2Dir(e.target.value) - setCsDir(e.target.value) + steam.setCsDir(e.target.value) }} /> -

当前用户64位SteamID:{currentUser().steamID64}

+

当前用户64位SteamID:{steam.currentUser().steamID64}

) diff --git a/src/components/cstb/FastLaunch.tsx b/src/components/cstb/FastLaunch.tsx index c73a0e1..da7f5d5 100644 --- a/src/components/cstb/FastLaunch.tsx +++ b/src/components/cstb/FastLaunch.tsx @@ -1,16 +1,13 @@ -import { steamStore } from "@/store/steam" -import { toolStore } from "@/store/tool" +import { useSteamStore } from "@/store/steam" +import { useToolStore } from "@/store/tool" import { TakeOff } from "@icon-park/react" import { invoke } from "@tauri-apps/api/core" -import { useSnapshot } from "valtio" import { Card, CardBody, CardHeader, CardIcon } from "../window/Card" // import { addToast } from "@heroui/react" const FastLaunch = () => { - void toolStore.start() - void steamStore.start() - const { launchOptions, launchIndex } = useSnapshot(toolStore.state) - const { dir } = useSnapshot(steamStore.state) + const steam = useSteamStore() + const tool = useToolStore() return ( @@ -25,8 +22,8 @@ const FastLaunch = () => { type="button" onClick={() => invoke("launch_game", { - steamPath: `${dir}/steam.exe`, - launchOption: launchOptions[launchIndex] || "", + steamPath: `${steam.state.dir}/steam.exe`, + launchOption: tool.state.launchOptions[tool.state.launchIndex] || "", server: "perfectworld", }) } @@ -38,8 +35,8 @@ const FastLaunch = () => { type="button" onClick={() => invoke("launch_game", { - steamPath: `${dir}/steam.exe`, - launchOption: launchOptions[launchIndex] || "", + steamPath: `${steam.state.dir}/steam.exe`, + launchOption: tool.state.launchOptions[tool.state.launchIndex] || "", server: "worldwide", }) } diff --git a/src/components/cstb/LaunchOption.tsx b/src/components/cstb/LaunchOption.tsx index 8a90508..c30aa1d 100644 --- a/src/components/cstb/LaunchOption.tsx +++ b/src/components/cstb/LaunchOption.tsx @@ -1,23 +1,16 @@ -import { - addLaunchOption, - setLaunchIndex, - setLaunchOption, - toolStore, -} from "@/store/tool" +import { useToolStore } from "@/store/tool" import { Plus, SettingConfig, Switch } from "@icon-park/react" import { useEffect, useState } from "react" -import { useSnapshot } from "valtio" import { Card, CardBody, CardHeader, CardIcon, CardTool } from "../window/Card" import { ToolButton } from "../window/ToolButton" const LaunchOption = () => { - void toolStore.start() - const { launchOptions, launchIndex } = useSnapshot(toolStore.state) - const [launchOpt, setLaunchOpt] = useState(launchOptions[launchIndex] || "") + const tool = useToolStore() + const [launchOpt, setLaunchOpt] = useState(tool.state.launchOptions[tool.state.launchIndex] || "") useEffect(() => { - setLaunchOpt(launchOptions[launchIndex] || "") - }, [launchIndex, launchOptions]) + setLaunchOpt(tool.state.launchOptions[tool.state.launchIndex] || "") + }, [tool.state.launchIndex, tool.state.launchOptions]) return ( @@ -26,12 +19,12 @@ const LaunchOption = () => { 启动选项 - {launchOptions.map((option, index) => ( - setLaunchIndex(index)}> + {tool.state.launchOptions.map((option, index) => ( + tool.setLaunchIndex(index)}> {index + 1} ))} - addLaunchOption("")}> + tool.addLaunchOption("")}> 添加 @@ -46,9 +39,9 @@ const LaunchOption = () => { placeholder="请输入启动选项" value={launchOpt} onChange={(e) => { - if (launchIndex < 0 || launchIndex > 10) return + if (tool.state.launchIndex < 0 || tool.state.launchIndex > 10) return setLaunchOpt(e.target.value) - setLaunchOption(e.target.value, launchIndex) + tool.setLaunchOption(e.target.value, tool.state.launchIndex) }} className="w-full font-mono text-base bg-transparent outline-none resize-none min-h-20" /> diff --git a/src/components/cstb/Notice.tsx b/src/components/cstb/Notice.tsx index 2f19f78..1943010 100644 --- a/src/components/cstb/Notice.tsx +++ b/src/components/cstb/Notice.tsx @@ -6,12 +6,11 @@ import { CardIcon, CardTool, } from "@/components/window/Card" -import { appStore } from "@/store/app" +import { useAppStore } from "@/store/app" import { createClient } from "@/utils/supabase/client" import { Skeleton } from "@heroui/react" import { Refresh, VolumeNotice } from "@icon-park/react" import useSWR, { useSWRConfig } from "swr" -import { useSnapshot } from "valtio" import { ToolButton } from "../window/ToolButton" const Notice = () => { @@ -38,8 +37,7 @@ const Notice = () => { } const NoticeBody = () => { - void appStore.start() - const app = useSnapshot(appStore.state) + const app = useAppStore() const noticeFetcher = async () => { const supabase = createClient() @@ -68,7 +66,7 @@ const NoticeBody = () => { return ( <> {notice?.content || - app.notice || + app.state.notice || "不会真的有人要更新CSGO工具箱吧,不会吧不会吧 xswl"} ) diff --git a/src/components/cstb/Prepare.tsx b/src/components/cstb/Prepare.tsx index 6861aaa..32cc0c2 100644 --- a/src/components/cstb/Prepare.tsx +++ b/src/components/cstb/Prepare.tsx @@ -1,27 +1,26 @@ import { Button, Spinner } from "@heroui/react" import { useRouter } from "next/navigation" import { useEffect, useState } from "react" -import { useSnapshot } from "valtio" -import { setCsDir, setDir, steamStore } from "@/store/steam" +import { useSteamStore } from "@/store/steam" import { open } from "@tauri-apps/plugin-dialog" export function Prepare() { + const steam = useSteamStore() const router = useRouter() - const steam = useSnapshot(steamStore.state) const [loading, setLoading] = useState(true) - const [steamDir, setSteamDir] = useState(steam.dir) - const [cs2Dir, setCs2Dir] = useState(steam.csDir) + const [steamDir, setSteamDir] = useState(steam.state.dir) + const [cs2Dir, setCs2Dir] = useState(steam.state.csDir) useEffect(() => { const checkPaths = () => { - if (steam.dir && steam.csDir) { - router.push("/home") - } else { - setLoading(false) + if (steam.state.dir && steam.state.csDir) { + // router.push("/home") } + + setLoading(false) } checkPaths() - }, [steam.dir, steam.csDir, router]) + }, [steam.state.dir, steam.state.csDir, router]) const handleSelectSteamDir = async () => { const selected = await open({ @@ -31,7 +30,7 @@ export function Prepare() { if (selected) { const dir = selected.replace(/\\[^\\]+$/, "") setSteamDir(dir) - setDir(dir) + steam.setDir(dir) } } @@ -42,14 +41,14 @@ export function Prepare() { }) if (selected) { setCs2Dir(selected) - setCsDir(selected) + steam.setCsDir(selected) } } if (loading) { return ( -
- +
+

正在检查路径...

) @@ -64,7 +63,9 @@ export function Prepare() { setSteamDir(e.target.value)} + onChange={(e) => { + setSteamDir(e.target.value), steam.setDir(e.target.value) + }} />
- + +
+ + +
) } diff --git a/src/components/window/Nav.tsx b/src/components/window/Nav.tsx index 5fbe105..0d90c70 100644 --- a/src/components/window/Nav.tsx +++ b/src/components/window/Nav.tsx @@ -1,7 +1,7 @@ "use client" import { setTheme as setTauriTheme } from "@/hooks/tauri/theme" -import { resetAppStore } from "@/store/app" -import { resetToolStore } from "@/store/tool" +import { useAppStore } from "@/store/app" +import { useToolStore } from "@/store/tool" import { addToast } from "@heroui/react" import { Close, Minus, Moon, Refresh, RocketOne, Square, SunOne } from "@icon-park/react" import { type Theme, getCurrentWindow } from "@tauri-apps/api/window" @@ -11,6 +11,8 @@ import { usePathname, useRouter } from "next/navigation" import { saveAllNow } from "tauri-plugin-valtio" const Nav = () => { + const app = useAppStore() + const tool = useToolStore() const { theme, setTheme } = useTheme() const setAppTheme = async (theme: Theme) => { setTheme(theme) @@ -46,8 +48,8 @@ const Nav = () => { type="button" className="px-2 py-0 transition duration-150 rounded hover:bg-zinc-200/80 dark:hover:bg-zinc-100/10 active:scale-95" onClick={() => { - resetAppStore() - resetToolStore() + app.resetAppStore() + tool.resetToolStore() addToast({ title: "重置成功", color: "success", diff --git a/src/components/window/SideBar.tsx b/src/components/window/SideBar.tsx index 92ab8db..4992e97 100644 --- a/src/components/window/SideBar.tsx +++ b/src/components/window/SideBar.tsx @@ -12,8 +12,7 @@ import { usePathname, useRouter } from "next/navigation" import type { ReactNode } from "react" // import { platform } from "@tauri-apps/plugin-os" -import { appStore, setVersion } from "@/store/app" -import { useSnapshot } from "valtio" +import { useAppStore } from "@/store/app" interface SideButtonProps { route: string @@ -71,8 +70,7 @@ const Avatar = () => { } const SideBar = () => { - void appStore.start() - const { version } = useSnapshot(appStore.state) + const app = useAppStore() return (
{ variant="light" size="sm" className="mt-0.5 text-zinc-600" - onPress={() => setVersion("x.y.z")} + onPress={() => app.setVersion("x.y.z")} > - {version} + {app.state.version}
diff --git a/src/store/app.ts b/src/store/app.ts index 5e686e5..cf166ac 100644 --- a/src/store/app.ts +++ b/src/store/app.ts @@ -1,13 +1,7 @@ import { store } from "tauri-plugin-valtio" +import { useSnapshot } from "valtio" import { DEFAULT_STORE_CONFIG } from "." -// Usage: -// import {appStore} from "@/store/app" -// import { useSnapshot } from "valtio" -// const app = useSnapshot(appStore.state) -// { app.version } -// () => appStore.setVersion("0.0.1") - const defaultValue = { version: "0.0.1", hasUpdate: false, @@ -18,26 +12,41 @@ const defaultValue = { export const appStore = store("app", { ...defaultValue }, DEFAULT_STORE_CONFIG) -export const setVersion = (version: string) => { +export const useAppStore = () => { + void appStore.start + const state = useSnapshot(appStore.state) + + return { + state, + setVersion, + setHasUpdate, + setInited, + setNotice, + setUseMirror, + resetAppStore, + } +} + +const setVersion = (version: string) => { appStore.state.version = version } -export const setHasUpdate = (hasUpdate: boolean) => { +const setHasUpdate = (hasUpdate: boolean) => { appStore.state.hasUpdate = hasUpdate } -export const setInited = (inited: boolean) => { +const setInited = (inited: boolean) => { appStore.state.inited = inited } -export const setNotice = (notice: string) => { +const setNotice = (notice: string) => { appStore.state.notice = notice } -export const setUseMirror = (useMirror: boolean) => { +const setUseMirror = (useMirror: boolean) => { appStore.state.useMirror = useMirror } -export const resetAppStore = () => { +const resetAppStore = () => { setVersion(defaultValue.version) setHasUpdate(defaultValue.hasUpdate) setInited(defaultValue.inited) setNotice(defaultValue.notice) setUseMirror(defaultValue.useMirror) -} +} \ No newline at end of file diff --git a/src/store/steam.ts b/src/store/steam.ts index 18edfc7..eca3154 100644 --- a/src/store/steam.ts +++ b/src/store/steam.ts @@ -1,6 +1,7 @@ import type { SteamUser } from "@/types/steam" import { store } from "tauri-plugin-valtio" import { DEFAULT_STORE_CONFIG } from "." +import { useSnapshot } from "valtio" const defaultValue = { dir: "C:\\Program Files (x86)\\Steam", @@ -18,33 +19,50 @@ const defaultValue = { isDirValid: false, isCsDirValid: false, } + export const steamStore = store( "steam", { ...defaultValue }, DEFAULT_STORE_CONFIG, ) -export const setDir = (dir: string) => { +export const useSteamStore = () => { + void steamStore.start + const state = useSnapshot(steamStore.state) + + return { + state, + setDir, + setCsDir, + setUsers, + setIsDirValid, + setIsCsDirValid, + currentUser, + resetSteamStore, + } +} + +const setDir = (dir: string) => { steamStore.state.dir = dir } -export const setCsDir = (dir: string) => { +const setCsDir = (dir: string) => { steamStore.state.csDir = dir } -export const setUsers = (users: SteamUser[]) => { +const setUsers = (users: SteamUser[]) => { steamStore.state.users = users } -export const setIsDirValid = (valid: boolean) => { +const setIsDirValid = (valid: boolean) => { steamStore.state.isDirValid = valid } -export const setIsCsDirValid = (valid: boolean) => { +const setIsCsDirValid = (valid: boolean) => { steamStore.state.isCsDirValid = valid } -export const currentUser = () => { +const currentUser = () => { return steamStore.state.users[0] || defaultValue.users[0] } -export const resetSteamStore = () => { +const resetSteamStore = () => { setDir(defaultValue.dir) setCsDir(defaultValue.csDir) setUsers(defaultValue.users) diff --git a/src/store/tool.ts b/src/store/tool.ts index eb2f3df..c3ec22c 100644 --- a/src/store/tool.ts +++ b/src/store/tool.ts @@ -1,6 +1,8 @@ import { store } from "tauri-plugin-valtio" +import { useSnapshot } from "valtio" import { DEFAULT_STORE_CONFIG } from "." + const defaultValue = { launchOptions: [ "-novid -high -freq 144 -fullscreen", @@ -17,7 +19,22 @@ export const toolStore = store( DEFAULT_STORE_CONFIG, ) -export const setLaunchOption = (option: string, index: number) => { +export const useToolStore = () => { + void toolStore.start + const state = useSnapshot(toolStore.state) + + return { + state, + setLaunchOption, + setLaunchOptions, + setLaunchIndex, + setPowerPlan, + addLaunchOption, + resetToolStore, + } +} + +const setLaunchOption = (option: string, index: number) => { toolStore.state.launchOptions = [ ...toolStore.state.launchOptions.slice(0, index), option, @@ -25,19 +42,19 @@ export const setLaunchOption = (option: string, index: number) => { ] } -export const setLaunchOptions = (options: string[]) => { +const setLaunchOptions = (options: string[]) => { toolStore.state.launchOptions = options } -export const setLaunchIndex = (index: number) => { +const setLaunchIndex = (index: number) => { toolStore.state.launchIndex = index } -export const setPowerPlan = (plan: number) => { +const setPowerPlan = (plan: number) => { toolStore.state.powerPlan = plan } -export const addLaunchOption = (option: string) => { +const addLaunchOption = (option: string) => { // 限制最高10个 if (toolStore.state.launchOptions.length >= 10) { return @@ -45,7 +62,7 @@ export const addLaunchOption = (option: string) => { toolStore.state.launchOptions = [...toolStore.state.launchOptions, option] } -export const resetToolStore = () => { +const resetToolStore = () => { setLaunchOptions(defaultValue.launchOptions) setLaunchIndex(defaultValue.launchIndex) setPowerPlan(defaultValue.powerPlan)