[feat] global watch dir and set better check logic

todo: first time check failed should let user manually click
This commit is contained in:
Purp1e
2025-03-21 02:42:49 +08:00
parent a9a48d2aba
commit c2c1a4c368
9 changed files with 99 additions and 60 deletions

BIN
bun.lockb

Binary file not shown.

View File

@@ -34,6 +34,7 @@
"@tauri-apps/plugin-store": "^2.2.0", "@tauri-apps/plugin-store": "^2.2.0",
"@tauri-store/valtio": "^2.0.0", "@tauri-store/valtio": "^2.0.0",
"@types/throttle-debounce": "^5.0.2", "@types/throttle-debounce": "^5.0.2",
"@uidotdev/usehooks": "^2.4.1",
"framer-motion": "^12.5.0", "framer-motion": "^12.5.0",
"jotai": "^2.12.2", "jotai": "^2.12.2",
"next": "15.2.2", "next": "15.2.2",

View File

@@ -6,10 +6,10 @@ export default function Page() {
return ( return (
<div className="flex flex-col items-start gap-3 pt-2 pb-1"> <div className="flex flex-col items-start gap-3 pt-2 pb-1">
<p>Steam路径{steam.state.dir}</p> <p>Steam路径{steam.state.steamDir}</p>
<p>{steam.state.csDir}</p> <p>{steam.state.cs2Dir}</p>
<p>Steam路径有效{steam.state.isDirValid ? "是" : "否"}</p> <p>Steam路径有效{steam.state.steamDirValid ? "是" : "否"}</p>
<p>{steam.state.isCsDirValid ? "是" : "否"}</p> <p>{steam.state.cs2DirValid ? "是" : "否"}</p>
<p>Steam账号{steam.currentUser().accountName}</p> <p>Steam账号{steam.currentUser().accountName}</p>
</div> </div>
) )

View File

@@ -1,14 +1,27 @@
"use client" "use client"
import { steamStore } from "@/store/steam" import { steamStore, useSteamStore } from "@/store/steam"
import { useEffect } from "react" import { useEffect } from "react"
import "./globals.css" import "./globals.css"
import Providers from "./providers" import Providers from "./providers"
import { init } from "@/store" import { init } from "@/store"
import { useDebounce } from "@uidotdev/usehooks"
export default function RootLayout({ children }: { children: React.ReactNode }) { export default function RootLayout({ children }: { children: React.ReactNode }) {
useEffect(() => { useEffect(() => {
void init() void init()
}) })
// 检测steam路径和游戏路径是否有效
const steam = useSteamStore()
const debounceSteamDir = useDebounce(steam.state.steamDir, 500)
const debounceCs2Dir = useDebounce(steam.state.cs2Dir, 500)
useEffect(() => {
steam.checkSteamDirValid()
}, [debounceSteamDir])
useEffect(() => {
steam.checkCs2DirValid()
}, [debounceCs2Dir])
return ( return (
<html lang="en"> <html lang="en">
<body> <body>

View File

@@ -4,13 +4,13 @@ import { useSteamStore } from "@/store/steam"
import { useEffect, useState } from "react" import { useEffect, useState } from "react"
export default function Page() { export default function Page() {
const steam = useSteamStore() const steam = useSteamStore()
const [steamDir, setSteamDir] = useState(steam.state.dir) const [steamDir, setSteamDir] = useState(steam.state.steamDir)
const [cs2Dir, setCs2Dir] = useState(steam.state.csDir) const [cs2Dir, setCs2Dir] = useState(steam.state.cs2Dir)
useEffect(() => { useEffect(() => {
setSteamDir(steam.state.dir) setSteamDir(steam.state.steamDir)
setCs2Dir(steam.state.csDir) setCs2Dir(steam.state.cs2Dir)
}, [steam.state.dir, steam.state.csDir]) }, [steam.state.steamDir, steam.state.cs2Dir])
return ( return (
<div <div

View File

@@ -22,7 +22,7 @@ const FastLaunch = () => {
type="button" type="button"
onClick={() => onClick={() =>
invoke("launch_game", { invoke("launch_game", {
steamPath: `${steam.state.dir}/steam.exe`, steamPath: `${steam.state.steamDir}/steam.exe`,
launchOption: tool.state.launchOptions[tool.state.launchIndex] || "", launchOption: tool.state.launchOptions[tool.state.launchIndex] || "",
server: "perfectworld", server: "perfectworld",
}) })
@@ -35,7 +35,7 @@ const FastLaunch = () => {
type="button" type="button"
onClick={() => onClick={() =>
invoke("launch_game", { invoke("launch_game", {
steamPath: `${steam.state.dir}/steam.exe`, steamPath: `${steam.state.steamDir}/steam.exe`,
launchOption: tool.state.launchOptions[tool.state.launchIndex] || "", launchOption: tool.state.launchOptions[tool.state.launchIndex] || "",
server: "worldwide", server: "worldwide",
}) })

View File

@@ -1,4 +1,4 @@
import { addToast, Button, Spinner } from "@heroui/react" import { addToast, Button, Chip, Spinner } from "@heroui/react"
import { useRouter } from "next/navigation" import { useRouter } from "next/navigation"
import { useEffect, useState } from "react" import { useEffect, useState } from "react"
import { steamStore, useSteamStore } from "@/store/steam" import { steamStore, useSteamStore } from "@/store/steam"
@@ -31,43 +31,33 @@ export function Prepare() {
const router = useRouter() const router = useRouter()
const [loading, setLoading] = useState(true) const [loading, setLoading] = useState(true)
const [checking, setChecking] = useState(false) const [checking, setChecking] = useState(false)
const [, setSteamDir] = useState(steam.state.dir) const [, setSteamDir] = useState(steam.state.steamDir)
const [, setCs2Dir] = useState(steam.state.csDir) const [, setCs2Dir] = useState(steam.state.cs2Dir)
const [inited, setInited] = useState(false) const [inited, setInited] = useState(false)
const [links, setLinks] = useState<string[]>([])
useEffect(() => { useEffect(() => {
const initValues = async () => { const initValues = async () => {
await steamStore.start() const initialSteamDir = steam.state.steamDir
const initialSteamDir = steam.state.dir const initialCs2Dir = steam.state.cs2Dir
const initialCs2Dir = steam.state.csDir
setSteamDir(initialSteamDir) setSteamDir(initialSteamDir)
setCs2Dir(initialCs2Dir) setCs2Dir(initialCs2Dir)
const allCheckPassed = steam.state.steamDirValid && steam.state.cs2DirValid
setInited(steam.state.steamDirValid && steam.state.cs2DirValid)
// 逻辑有点问题,第一次启动时检查成功直接跳转,第一次检查失败不跳转,用户手动点击
if (allCheckPassed) {
router.push("/home")
return
}
setTimeout(() => {
setLoading(false)
}, 300)
} }
void initValues() void initValues()
}) })
useEffect(() => {
void onOpenUrl((urls) => {
console.log("deep link:", urls)
setLinks(urls)
})
const checkPaths = async () => {
setChecking(true)
const exist: boolean =
(await check_path(path.resolve(steam.state.dir, "steam.exe"))) &&
(await check_path(path.resolve(steam.state.csDir, "cs2.exe")))
setTimeout(() => {
setInited(exist)
setLoading(false)
setChecking(false)
}, 500)
}
void checkPaths()
}, [steam.state.dir, steam.state.csDir, router])
const handleSelectSteamDir = async () => { const handleSelectSteamDir = async () => {
const selected = await open({ const selected = await open({
title: "选择 Steam.exe 文件", title: "选择 Steam.exe 文件",
@@ -135,7 +125,7 @@ export function Prepare() {
<div className="flex gap-2"> <div className="flex gap-2">
<input <input
className="flex-grow px-2 py-1 mb-2 rounded-lg" className="flex-grow px-2 py-1 mb-2 rounded-lg"
value={steam.state.dir} value={steam.state.steamDir}
onChange={(e) => { onChange={(e) => {
setSteamDir(e.target.value) setSteamDir(e.target.value)
steam.setDir(e.target.value) steam.setDir(e.target.value)
@@ -149,7 +139,7 @@ export function Prepare() {
<div className="flex gap-2"> <div className="flex gap-2">
<input <input
className="flex-grow px-2 py-1 mb-2 rounded-lg" className="flex-grow px-2 py-1 mb-2 rounded-lg"
value={steam.state.csDir} value={steam.state.cs2Dir}
onChange={(e) => { onChange={(e) => {
setCs2Dir(e.target.value) setCs2Dir(e.target.value)
steam.setCsDir(e.target.value) steam.setCsDir(e.target.value)
@@ -160,7 +150,12 @@ export function Prepare() {
</Button> </Button>
</div> </div>
{links.length > 0 && <p className="text-white">{links}</p>} <TestDeepLink />
<section className="flex justify-center gap-3">
<Chip>{steam.state.steamDirValid ? "Steam √" : "Steam ×"}</Chip>
<Chip>{steam.state.cs2DirValid ? "CS2 √" : "CS2 ×"}</Chip>
</section>
<section className="flex justify-center w-full gap-3 mt-6"> <section className="flex justify-center w-full gap-3 mt-6">
<Button onPress={() => void autoGetPaths()} variant="ghost" color="default" size="sm"> <Button onPress={() => void autoGetPaths()} variant="ghost" color="default" size="sm">
@@ -180,3 +175,16 @@ export function Prepare() {
</div> </div>
) )
} }
function TestDeepLink() {
const [links, setLinks] = useState<string[]>([])
const router = useRouter()
useEffect(() => {
void onOpenUrl((urls) => {
console.log("deep link:", urls)
setLinks(urls)
})
}, [router])
return <>{links.length > 0 && <p className="text-white">{links}</p>}</>
}

View File

@@ -10,6 +10,5 @@ export async function init() {
await toolStore.start() await toolStore.start()
await steamStore.start() await steamStore.start()
const appConfigDirPath = await appConfigDir() const appConfigDirPath = await appConfigDir()
console.log(appConfigDirPath)
await setStoreCollectionPath(path.resolve(appConfigDirPath, "cstb")) await setStoreCollectionPath(path.resolve(appConfigDirPath, "cstb"))
} }

View File

@@ -2,10 +2,14 @@ import type { SteamUser } from "@/types/steam"
import { store } from "@tauri-store/valtio" import { store } from "@tauri-store/valtio"
import { DEFAULT_STORE_CONFIG } from "./config" import { DEFAULT_STORE_CONFIG } from "./config"
import { useSnapshot } from "valtio" import { useSnapshot } from "valtio"
import { useEffect } from "react"
import { addToast } from "@heroui/react"
import { invoke } from "@tauri-apps/api/core"
import { dir } from "console"
const defaultValue = { const defaultValue = {
dir: "C:\\Program Files (x86)\\Steam", steamDir: "C:\\Program Files (x86)\\Steam",
csDir: "", cs2Dir: "",
users: [ users: [
{ {
steamID64: "76561198052315353", steamID64: "76561198052315353",
@@ -16,8 +20,8 @@ const defaultValue = {
avatar: "", avatar: "",
}, },
] as SteamUser[], ] as SteamUser[],
isDirValid: false, steamDirValid: false,
isCsDirValid: false, cs2DirValid: false,
} }
export const steamStore = store( export const steamStore = store(
@@ -35,27 +39,41 @@ export const useSteamStore = () => {
setDir, setDir,
setCsDir, setCsDir,
setUsers, setUsers,
setIsDirValid, setSteamDirValid,
setIsCsDirValid, setCs2DirValid,
checkSteamDirValid,
checkCs2DirValid,
currentUser, currentUser,
resetSteamStore, resetSteamStore,
} }
} }
const setDir = (dir: string) => { const setDir = (dir: string) => {
steamStore.state.dir = dir steamStore.state.steamDir = dir
} }
const setCsDir = (dir: string) => { const setCsDir = (dir: string) => {
steamStore.state.csDir = dir steamStore.state.cs2Dir = dir
} }
const setUsers = (users: SteamUser[]) => { const setUsers = (users: SteamUser[]) => {
steamStore.state.users = users steamStore.state.users = users
} }
const setIsDirValid = (valid: boolean) => { const setSteamDirValid = (valid: boolean) => {
steamStore.state.isDirValid = valid steamStore.state.steamDirValid = valid
} }
const setIsCsDirValid = (valid: boolean) => { const setCs2DirValid = (valid: boolean) => {
steamStore.state.isCsDirValid = valid steamStore.state.cs2DirValid = valid
}
const checkSteamDirValid = async () => {
const pathExist = await invoke<boolean>("check_path", { path: steamStore.state.steamDir })
console.log("steamDir", steamStore.state.steamDir, "pathExist", pathExist)
setSteamDirValid(pathExist)
}
const checkCs2DirValid = async () => {
const pathExist = await invoke<boolean>("check_path", { path: steamStore.state.cs2Dir })
console.log("cs2Dir", steamStore.state.cs2Dir, "pathExist", pathExist)
setCs2DirValid(pathExist)
} }
const currentUser = () => { const currentUser = () => {
@@ -63,9 +81,9 @@ const currentUser = () => {
} }
const resetSteamStore = () => { const resetSteamStore = () => {
setDir(defaultValue.dir) setDir(defaultValue.steamDir)
setCsDir(defaultValue.csDir) setCsDir(defaultValue.cs2Dir)
setUsers(defaultValue.users) setUsers(defaultValue.users)
setIsDirValid(defaultValue.isDirValid) setSteamDirValid(defaultValue.steamDirValid)
setIsCsDirValid(defaultValue.isCsDirValid) setCs2DirValid(defaultValue.cs2DirValid)
} }