mirror of
https://github.com/dream-pep/koring-launcher.git
synced 2026-09-12 05:45:18 +08:00
feat(update页面): 添加滚动自动隐藏底部操作栏的功能
为滚动容器添加 id="app-content-scroll" 以支持滚动监听 新增滚动逻辑,非繁忙状态下向下滚动时隐藏底部栏,向上滚动或回顶时恢复显示 繁忙状态(下载、暂停、安装、检查更新)下始终显示底部栏 使用 clsx 优化底部栏的条件类名并添加平滑过渡动画
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -38,6 +38,7 @@ export function RootLayout({
|
|||||||
|
|
||||||
{/* Layer 1: Content */}
|
{/* Layer 1: Content */}
|
||||||
<div
|
<div
|
||||||
|
id="app-content-scroll"
|
||||||
className="absolute z-[1] left-0 right-0 bottom-0 top-[40px] overflow-auto"
|
className="absolute z-[1] left-0 right-0 bottom-0 top-[40px] overflow-auto"
|
||||||
style={{ viewTransitionName: "content" } as React.CSSProperties}
|
style={{ viewTransitionName: "content" } as React.CSSProperties}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
import { ExternalLink, Loader2, RefreshCw } from "lucide-react";
|
import { ExternalLink, Loader2, RefreshCw } from "lucide-react";
|
||||||
import { Button, Link } from "@heroui/react";
|
import { Button, Link } from "@heroui/react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
import clsx from "clsx";
|
||||||
import ReactMarkdown from "react-markdown";
|
import ReactMarkdown from "react-markdown";
|
||||||
import remarkGfm from "remark-gfm";
|
import remarkGfm from "remark-gfm";
|
||||||
import rehypeRaw from "rehype-raw";
|
import rehypeRaw from "rehype-raw";
|
||||||
@@ -99,6 +100,36 @@ export function UpdatePage() {
|
|||||||
const isDownloading = st === "downloading";
|
const isDownloading = st === "downloading";
|
||||||
const isPaused = st === "paused";
|
const isPaused = st === "paused";
|
||||||
|
|
||||||
|
// 底部遮罩滚动感知:向下滚动(阅读发布说明)自动收起,向上滚动/回顶恢复。
|
||||||
|
// 下载/暂停/安装/检查等需要常驻进度条的状态下始终显示。
|
||||||
|
const [barVisible, setBarVisible] = useState(true);
|
||||||
|
useEffect(() => {
|
||||||
|
const el = document.getElementById("app-content-scroll");
|
||||||
|
if (!el) return;
|
||||||
|
const busy = st === "downloading" || st === "paused" || st === "installing" || st === "checking";
|
||||||
|
let lastY = el.scrollTop;
|
||||||
|
let ticking = false;
|
||||||
|
const onScroll = () => {
|
||||||
|
if (ticking) return;
|
||||||
|
ticking = true;
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
const y = el.scrollTop;
|
||||||
|
const delta = y - lastY;
|
||||||
|
if (busy) {
|
||||||
|
setBarVisible(true);
|
||||||
|
} else if (delta > 16 && y > 160) {
|
||||||
|
setBarVisible(false);
|
||||||
|
} else if (delta < -16 || y < 80) {
|
||||||
|
setBarVisible(true);
|
||||||
|
}
|
||||||
|
lastY = y;
|
||||||
|
ticking = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
el.addEventListener("scroll", onScroll, { passive: true });
|
||||||
|
return () => el.removeEventListener("scroll", onScroll);
|
||||||
|
}, [st]);
|
||||||
|
|
||||||
const handleCheck = async () => {
|
const handleCheck = async () => {
|
||||||
try {
|
try {
|
||||||
await checkForUpdates(true);
|
await checkForUpdates(true);
|
||||||
@@ -234,9 +265,13 @@ export function UpdatePage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 底部遮罩:fixed 吸附底部,样式与顶栏一致;驱动整个更新流程 */}
|
{/* 底部遮罩:fixed 吸附底部,样式与顶栏一致;驱动整个更新流程。
|
||||||
|
阅读时向下滚动自动收起(translate-y-full),向上滚动/回顶恢复 */}
|
||||||
<div
|
<div
|
||||||
className="fixed bottom-0 left-0 right-0 z-20"
|
className={clsx(
|
||||||
|
"fixed bottom-0 left-0 right-0 z-20 transition-transform duration-300",
|
||||||
|
barVisible ? "translate-y-0" : "translate-y-full",
|
||||||
|
)}
|
||||||
style={{
|
style={{
|
||||||
background: "var(--titlebar-bg)",
|
background: "var(--titlebar-bg)",
|
||||||
backdropFilter: "blur(3px)",
|
backdropFilter: "blur(3px)",
|
||||||
|
|||||||
Reference in New Issue
Block a user