20260723存档01

This commit is contained in:
2026-07-23 01:29:55 +08:00
parent 0a2b8bd018
commit cdbb1e54a3
13 changed files with 774 additions and 82 deletions
+8
View File
@@ -7,12 +7,14 @@ import { syncThemeFromConfig } from "./stores/themeStore";
import { syncA11yFromConfig } from "./stores/a11yStore";
import { syncBackgroundFromConfig } from "./stores/backgroundStore";
import { useAuthStore } from "./stores/authStore";
import { useKoringAuthStore } from "./stores/koringAuthStore";
import type { AppConfig } from "./api/config";
import { Home } from "./pages/home";
import { Store } from "./pages/store";
import { Today } from "./pages/today";
import { PlayLink } from "./pages/play-link";
import { Setting } from "./pages/setting";
import { SettingLogin } from "./pages/setting/login";
import { Gallery } from "./pages/gallery";
import { TaskQueue } from "./pages/task-queue";
import { Debug } from "./pages/debug";
@@ -24,6 +26,8 @@ import { CrashDebug } from "./pages/debug/crash-debug";
import { Oobe } from "./pages/oobe";
import { OobeLanguage } from "./pages/oobe/step-language";
import { OobeAgreement } from "./pages/oobe/step-agreement";
import { OobeLogin } from "./pages/oobe/step-login";
import { OobeWelcome } from "./pages/oobe/step-welcome";
import { OobeVersion } from "./pages/oobe/step-version";
import { OobeBetaTest } from "./pages/oobe/step-beta-test";
import { OobeFinish } from "./pages/oobe/step-finish";
@@ -35,11 +39,14 @@ const pageMap = {
today: Today,
"play-link": PlayLink,
setting: Setting,
"setting/login": SettingLogin,
gallery: Gallery,
"task-queue": TaskQueue,
oobe: Oobe,
"oobe/language": OobeLanguage,
"oobe/agreement": OobeAgreement,
"oobe/login": OobeLogin,
"oobe/welcome": OobeWelcome,
"oobe/version": OobeVersion,
"oobe/beta-test": OobeBetaTest,
"oobe/finish": OobeFinish,
@@ -66,6 +73,7 @@ function App() {
syncA11yFromConfig();
syncBackgroundFromConfig();
useAuthStore.getState().initFromRegistry();
useKoringAuthStore.getState().initFromDisk();
// Navigate to OOBE on first launch or if oobe not completed
if (isFirstLaunch || config.oobe) {
useRouteStore.getState().navigate("oobe");
+1
View File
@@ -1,4 +1,5 @@
@import "tailwindcss";
@import "@heroui/styles";
@import "tw-animate-css";
@import "shadcn/tailwind.css";
@import "sonner/dist/styles.css";
+1 -1
View File
@@ -54,7 +54,7 @@ export function OobeAgreement() {
</label>
</div>
<NextButton onClick={() => navigate("oobe/version")} disabled={!checked} />
<NextButton onClick={() => navigate("oobe/welcome")} disabled={!checked} />
</OobeLayout>
);
}
+1 -1
View File
@@ -45,7 +45,7 @@ export function OobeLanguage() {
))}
</div>
<NextButton onClick={() => navigate("oobe/agreement")} />
<NextButton onClick={() => navigate("oobe/login")} />
</OobeLayout>
);
}
+1 -1
View File
@@ -12,7 +12,7 @@ export function OobeVersion() {
const isTestBuild = BUILD_MODE === "dev" || BUILD_MODE === "beta";
const badgeLabel = BUILD_MODE === "dev" ? "DEV" : BUILD_MODE === "beta" ? "BETA" : null;
const nextRoute = isTestBuild ? "oobe/beta-test" : "oobe/finish";
const nextRoute = isTestBuild ? "oobe/beta-test" : "oobe/login";
useEffect(() => {
fetch(`${import.meta.env.BASE_URL}changelog-${VERSION}.txt`)
+60 -71
View File
@@ -1,25 +1,19 @@
import { useAuthStore } from "@/stores/authStore";
import { Button } from "@/components/ui/button";
import { UserCircle, LogOut, RefreshCw } from "lucide-react";
import { useEffect } from "react";
import { useKoringAuthStore } from "@/stores/koringAuthStore";
import { useRouteStore } from "@/stores/routeStore";
import { UserCircle, LogOut, Loader2, ChevronRight } from "lucide-react";
function GlassCard({ children }: { children: React.ReactNode }) {
return <div className="glass-card px-5 py-4">{children}</div>;
}
function SettingRow({ label, desc, children }: { label: string; desc?: string; children: React.ReactNode }) {
return (
<div className="flex items-center justify-between gap-4">
<div className="flex-1 min-w-0">
<p className="text-sm font-medium text-foreground">{label}</p>
{desc && <p className="text-[13px] text-muted-foreground mt-0.5">{desc}</p>}
</div>
<div className="shrink-0">{children}</div>
</div>
);
}
export function AccountSetting() {
const { user, loading, logout, startMicrosoftLogin } = useAuthStore();
const { user, loading, initFromDisk, logout } = useKoringAuthStore();
const navigate = useRouteStore((s) => s.navigate);
useEffect(() => {
initFromDisk();
}, [initFromDisk]);
return (
<div>
@@ -27,24 +21,39 @@ export function AccountSetting() {
<p className="text-sm text-muted-foreground mb-6"> Koring </p>
<div className="space-y-6">
{/* ===== 账户信息 ===== */}
{/* 账户信息 */}
<div>
<h3 className="text-lg font-bold text-foreground mb-3"></h3>
<GlassCard>
{user ? (
<button
onClick={() => {
if (!user && !loading) navigate("setting/login");
}}
className={[
"glass-card px-5 py-4 w-full text-left transition-all duration-200",
!user && !loading ? "cursor-pointer hover:bg-foreground/[0.04]" : "cursor-default",
].join(" ")}
>
{loading ? (
<div className="flex items-center gap-2 py-2">
<Loader2 className="w-4 h-4 animate-spin text-muted-foreground" />
<span className="text-sm text-muted-foreground">...</span>
</div>
) : user ? (
<div className="flex items-center gap-4">
<div className="w-14 h-14 rounded-full bg-foreground/[0.06] flex items-center justify-center shrink-0">
<UserCircle className="w-8 h-8 text-foreground/40" />
<div className="w-14 h-14 rounded-full bg-foreground/[0.06] flex items-center justify-center shrink-0 overflow-hidden">
{user.picture ? (
<img src={user.picture} alt="" className="w-full h-full object-cover" />
) : (
<UserCircle className="w-8 h-8 text-foreground/40" />
)}
</div>
<div className="flex-1 min-w-0">
<p className="text-base font-medium text-foreground truncate">{user.username}</p>
<p className="text-[13px] text-muted-foreground mt-0.5">
{user.xboxProfile ? "Microsoft 账户" : "本地账户"}
<p className="text-base font-medium text-foreground truncate">
{user.name || user.username}
</p>
{user.uuid && (
<p className="text-[11px] text-muted-foreground/60 mt-0.5 font-mono">
UUID: {user.uuid}
</p>
<p className="text-[13px] text-muted-foreground mt-0.5">Koring </p>
{user.email && (
<p className="text-[11px] text-muted-foreground/60 mt-0.5">{user.email}</p>
)}
</div>
</div>
@@ -55,56 +64,36 @@ export function AccountSetting() {
</div>
<div className="flex-1 min-w-0">
<p className="text-sm text-muted-foreground"></p>
<p className="text-[12px] text-muted-foreground/60 mt-0.5"></p>
<p className="text-[12px] text-muted-foreground/60 mt-0.5"> Koring </p>
</div>
<ChevronRight className="w-4 h-4 text-foreground/20 shrink-0" />
</div>
)}
</GlassCard>
</button>
</div>
{/* ===== 账户操作 ===== */}
<div>
<h3 className="text-lg font-bold text-foreground mb-3"></h3>
<div className="space-y-3">
{user ? (
<>
<GlassCard>
<SettingRow
label="同步数据"
desc="立即拉取最新的云端配置与数据"
>
<Button variant="outline" size="sm" disabled={loading}>
<RefreshCw className="w-3.5 h-3.5 mr-1.5" />
</Button>
</SettingRow>
</GlassCard>
<GlassCard>
<SettingRow
label="退出登录"
desc="退出当前账户,数据将保留在本地"
>
<Button variant="destructive" size="sm" onClick={logout} disabled={loading}>
<LogOut className="w-3.5 h-3.5 mr-1.5" />
退
</Button>
</SettingRow>
</GlassCard>
</>
) : (
<GlassCard>
<SettingRow
label="登录 Koring 账户"
desc="通过 Microsoft 账户登录以同步数据、皮肤与个人配置"
{/* 退出登录 */}
{user && (
<div>
<h3 className="text-lg font-bold text-foreground mb-3"></h3>
<GlassCard>
<div className="flex items-center justify-between">
<div>
<p className="text-sm font-medium text-foreground">退</p>
<p className="text-[13px] text-muted-foreground mt-0.5">退</p>
</div>
<button
onClick={logout}
disabled={loading}
className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-md text-[13px] font-medium bg-red-500/10 text-red-600 dark:text-red-400 hover:bg-red-500/20 transition-colors disabled:opacity-40"
>
<Button size="sm" onClick={() => startMicrosoftLogin("00000000-0000-0000-0000-000000000000")} disabled={loading}>
</Button>
</SettingRow>
</GlassCard>
)}
<LogOut className="w-3.5 h-3.5" />
退
</button>
</div>
</GlassCard>
</div>
</div>
)}
</div>
</div>
);
+11 -8
View File
@@ -1,4 +1,5 @@
import { useAuthStore } from "@/stores/authStore";
import { useKoringAuthStore } from "@/stores/koringAuthStore";
import { useRouteStore } from "@/stores/routeStore";
import { BUILD_MODE } from "@/lib/mode";
import { useUpdateStore } from "@/stores/updateStore";
import {
@@ -62,7 +63,7 @@ interface HomeSettingProps {
}
export function HomeSetting({ onNavigate }: HomeSettingProps) {
const user = useAuthStore((s) => s.user);
const user = useKoringAuthStore((s) => s.user);
const { update } = useUpdateStore();
return (
@@ -85,17 +86,19 @@ export function HomeSetting({ onNavigate }: HomeSettingProps) {
<h3 className="text-lg font-bold text-foreground mb-3"></h3>
<GlassCard>
<div className="flex items-center gap-4">
<div className="w-12 h-12 rounded-full bg-foreground/[0.06] flex items-center justify-center shrink-0">
<UserCircle className="w-7 h-7 text-foreground/40" />
<div className="w-12 h-12 rounded-full bg-foreground/[0.06] flex items-center justify-center shrink-0 overflow-hidden">
{user?.picture ? (
<img src={user.picture} alt="" className="w-full h-full object-cover" />
) : (
<UserCircle className="w-7 h-7 text-foreground/40" />
)}
</div>
<div className="flex-1 min-w-0">
<p className="text-sm font-medium text-foreground truncate">
{user?.username ?? "未登录"}
{user ? (user.name || user.username) : "未登录"}
</p>
<p className="text-[12px] text-muted-foreground mt-0.5">
{user
? `${user.xboxProfile ? "Microsoft" : "离线"} 账户`
: "登录以同步数据和皮肤"}
{user ? "Koring 账户" : "登录以同步数据和皮肤"}
</p>
</div>
<span className="text-[11px] text-muted-foreground shrink-0">
+6
View File
@@ -6,6 +6,7 @@ export type RouteKey =
| "today"
| "play-link"
| "setting"
| "setting/login"
| "gallery"
| "task-queue"
| "oobe"
@@ -13,6 +14,8 @@ export type RouteKey =
| "oobe/agreement"
| "oobe/version"
| "oobe/beta-test"
| "oobe/login"
| "oobe/welcome"
| "oobe/finish"
| "oobe/about-info"
| "debug"
@@ -45,12 +48,15 @@ export const routes: RouteItem[] = [
export const allRoutes: RouteItem[] = [
...routes,
{ key: "setting/login", label: "登录", path: "/setting/login", hidden: true, backable: true },
{ key: "task-queue", label: "任务队列", path: "/task-queue", hidden: true },
{ key: "oobe", label: "OOBE", path: "/oobe", hidden: true },
{ key: "oobe/language", label: "语言设置", path: "/oobe/language", hidden: true },
{ key: "oobe/agreement", label: "同意协议", path: "/oobe/agreement", hidden: true },
{ key: "oobe/version", label: "当前版本", path: "/oobe/version", hidden: true },
{ key: "oobe/beta-test", label: "测试协议", path: "/oobe/beta-test", hidden: true },
{ key: "oobe/login", label: "登录", path: "/oobe/login", hidden: true },
{ key: "oobe/welcome", label: "欢迎", path: "/oobe/welcome", hidden: true },
{ key: "oobe/finish", label: "完成", path: "/oobe/finish", hidden: true },
{ key: "oobe/about-info", label: "关于信息", path: "/oobe/about-info", hidden: true, backable: true },
{ key: "debug", label: "调试", path: "/debug", hidden: true },