feat: 新增主页沉浸模式开关

This commit is contained in:
JSR
2026-03-27 20:55:04 +08:00
parent 86f0c722bc
commit f83e8905e1
2 changed files with 84 additions and 29 deletions
+34 -1
View File
@@ -14,6 +14,7 @@ function MainContent(): React.JSX.Element {
const { currentTheme } = useTheme()
const [messageApi, contextHolder] = message.useMessage()
const { isIosDevice, isAndroidDevice, defaultPortraitMode } = useMemo(getMobileDeviceInfo, [])
const [immersiveMode, setImmersiveMode] = useState(false)
useEffect(() => {
const api = (window as any).api
@@ -27,6 +28,11 @@ function MainContent(): React.JSX.Element {
const currentPath = location.pathname === "/" ? "/home" : location.pathname
const targetPath = route === "/" ? "/home" : route
if (immersiveMode && !targetPath.startsWith("/home")) {
navigate("/", { replace: true })
return
}
if (currentPath !== targetPath) {
navigate(route)
}
@@ -44,7 +50,7 @@ function MainContent(): React.JSX.Element {
disposed = true
if (unlisten) unlisten()
}
}, [navigate, location.pathname])
}, [navigate, location.pathname, immersiveMode])
const [wizardVisible, setWizardVisible] = useState(false)
const [permission, setPermission] = useState<"admin" | "points" | "view">("view")
@@ -302,6 +308,7 @@ function MainContent(): React.JSX.Element {
const onMenuChange = (v: string) => {
const key = String(v)
if (immersiveMode && key !== "home") return
if (key === "home") navigate("/")
if (key === "students") navigate("/students")
if (key === "score") navigate("/score")
@@ -315,6 +322,7 @@ function MainContent(): React.JSX.Element {
}
const toggleSidebar = () => {
if (immersiveMode) return
if (isPortraitMode && sidebarCollapsed) {
setFloatingSidebarExpanded((prev) => !prev)
return
@@ -322,6 +330,26 @@ function MainContent(): React.JSX.Element {
setSidebarCollapsed((prev) => !prev)
}
useEffect(() => {
if (!immersiveMode) return
if (location.pathname !== "/" && !location.pathname.startsWith("/home")) {
navigate("/", { replace: true })
}
}, [immersiveMode, location.pathname, navigate])
const toggleImmersiveMode = () => {
setImmersiveMode((prev) => {
const next = !prev
if (next) {
setFloatingSidebarExpanded(false)
if (location.pathname !== "/" && !location.pathname.startsWith("/home")) {
navigate("/", { replace: true })
}
}
return next
})
}
const isDark = currentTheme?.mode === "dark"
const brandColor = currentTheme?.config?.tdesign?.brandColor || "#0052D9"
@@ -338,6 +366,7 @@ function MainContent(): React.JSX.Element {
>
{contextHolder}
<Layout style={{ height: "100%", flexDirection: "row", overflow: "hidden" }}>
{!immersiveMode && (
<Sidebar
activeMenu={activeMenu}
permission={permission}
@@ -347,6 +376,7 @@ function MainContent(): React.JSX.Element {
floatingExpanded={floatingSidebarExpanded}
onFloatingExpandedChange={setFloatingSidebarExpanded}
/>
)}
<ContentArea
permission={permission}
hasAnyPassword={hasAnyPassword}
@@ -358,6 +388,9 @@ function MainContent(): React.JSX.Element {
floatingExpand={isPortraitMode}
floatingExpanded={floatingSidebarExpanded}
onToggleSidebar={toggleSidebar}
immersiveMode={immersiveMode}
isHomePage={activeMenu === "home"}
onToggleImmersiveMode={toggleImmersiveMode}
/>
<OOBE visible={wizardVisible} onComplete={() => setWizardVisible(false)} />
+23 -1
View File
@@ -1,6 +1,11 @@
import React, { Suspense, lazy, useEffect } from "react"
import { Layout, Space, Button, Tag, Spin } from "antd"
import { MenuFoldOutlined, MenuUnfoldOutlined } from "@ant-design/icons"
import {
MenuFoldOutlined,
MenuUnfoldOutlined,
FullscreenOutlined,
FullscreenExitOutlined,
} from "@ant-design/icons"
import { Routes, Route, Navigate } from "react-router-dom"
import { useTranslation } from "react-i18next"
import { WindowControls } from "./WindowControls"
@@ -58,6 +63,9 @@ interface ContentAreaProps {
floatingExpand: boolean
floatingExpanded: boolean
onToggleSidebar: () => void
immersiveMode: boolean
isHomePage: boolean
onToggleImmersiveMode: () => void
}
export function ContentArea({
@@ -71,6 +79,9 @@ export function ContentArea({
floatingExpand,
floatingExpanded,
onToggleSidebar,
immersiveMode,
isHomePage,
onToggleImmersiveMode,
}: ContentAreaProps): React.JSX.Element {
const { t } = useTranslation()
@@ -144,6 +155,7 @@ export function ContentArea({
} as React.CSSProperties
}
>
{!immersiveMode && (
<Button
type="text"
size="small"
@@ -164,6 +176,7 @@ export function ContentArea({
title={sidebarCollapsed ? "展开导航栏" : "收起导航栏"}
style={{ width: "32px", height: "32px" }}
/>
)}
</div>
<div
data-tauri-drag-region
@@ -186,6 +199,15 @@ export function ContentArea({
}
>
<Space size="small">
{(immersiveMode || isHomePage) && (
<Button
size="small"
type={immersiveMode ? "primary" : "default"}
icon={immersiveMode ? <FullscreenExitOutlined /> : <FullscreenOutlined />}
onClick={onToggleImmersiveMode}
title={immersiveMode ? "退出沉浸模式" : "进入沉浸模式"}
/>
)}
{permissionTag}
{hasAnyPassword && (
<>