新增首页灵感推荐瀑布流
Project CI / Repository checks (pull_request) Successful in 4m18s
Project CI / Frontend tests (pull_request) Successful in 4m24s
Project CI / Backend tests (pull_request) Successful in 5m58s
Project CI / Native shell tests (pull_request) Successful in 14m24s

新增 23 张内置灵感图片素材

实现响应式瀑布流和纵向滚动

支持图片全屏预览与遮罩关闭

补充首页交互测试和技术文档
This commit is contained in:
2026-08-25 18:58:54 +08:00
parent 05e11b11ca
commit 2773bcc5af
27 changed files with 141 additions and 5 deletions
@@ -0,0 +1,118 @@
import { useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import inspiration01 from './assets/inspiration/inspiration-01.webp';
import inspiration02 from './assets/inspiration/inspiration-02.webp';
import inspiration03 from './assets/inspiration/inspiration-03.webp';
import inspiration04 from './assets/inspiration/inspiration-04.webp';
import inspiration05 from './assets/inspiration/inspiration-05.webp';
import inspiration06 from './assets/inspiration/inspiration-06.webp';
import inspiration07 from './assets/inspiration/inspiration-07.webp';
import inspiration08 from './assets/inspiration/inspiration-08.webp';
import inspiration09 from './assets/inspiration/inspiration-09.webp';
import inspiration10 from './assets/inspiration/inspiration-10.webp';
import inspiration11 from './assets/inspiration/inspiration-11.webp';
import inspiration12 from './assets/inspiration/inspiration-12.webp';
import inspiration13 from './assets/inspiration/inspiration-13.webp';
import inspiration14 from './assets/inspiration/inspiration-14.webp';
import inspiration15 from './assets/inspiration/inspiration-15.webp';
import inspiration16 from './assets/inspiration/inspiration-16.webp';
import inspiration17 from './assets/inspiration/inspiration-17.webp';
import inspiration18 from './assets/inspiration/inspiration-18.webp';
import inspiration19 from './assets/inspiration/inspiration-19.webp';
import inspiration20 from './assets/inspiration/inspiration-20.webp';
import inspiration21 from './assets/inspiration/inspiration-21.webp';
import inspiration22 from './assets/inspiration/inspiration-22.webp';
import inspiration23 from './assets/inspiration/inspiration-23.webp';
const INSPIRATION_IMAGES = [
inspiration01,
inspiration02,
inspiration03,
inspiration04,
inspiration05,
inspiration06,
inspiration07,
inspiration08,
inspiration09,
inspiration10,
inspiration11,
inspiration12,
inspiration13,
inspiration14,
inspiration15,
inspiration16,
inspiration17,
inspiration18,
inspiration19,
inspiration20,
inspiration21,
inspiration22,
inspiration23,
] as const;
export default function InspirationGallery() {
const [selectedImage, setSelectedImage] = useState<string | null>(null);
useEffect(() => {
if (!selectedImage) {
return;
}
const previousOverflow = document.body.style.overflow;
document.body.style.overflow = 'hidden';
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
setSelectedImage(null);
}
};
window.addEventListener('keydown', handleKeyDown);
return () => {
document.body.style.overflow = previousOverflow;
window.removeEventListener('keydown', handleKeyDown);
};
}, [selectedImage]);
return (
<>
<div className="columns-3 gap-3 max-[760px]:columns-2 max-[460px]:columns-1">
{INSPIRATION_IMAGES.map((image, index) => (
<button
className="mb-3 block w-full cursor-zoom-in break-inside-avoid overflow-hidden rounded-lg border-0 bg-transparent p-0 shadow-(--platform-panel-shadow) transition duration-200 hover:-translate-y-0.5 hover:shadow-(--platform-profile-action-shadow) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--platform-warm-text)"
type="button"
key={image}
aria-label={`查看灵感图片 ${index + 1}`}
onClick={() => setSelectedImage(image)}
>
<img
className="block h-auto w-full"
src={image}
alt=""
loading="lazy"
decoding="async"
/>
</button>
))}
</div>
{selectedImage
? createPortal(
<div
className="fixed inset-0 z-[1000] grid cursor-zoom-out place-items-center bg-black/80 p-6"
role="dialog"
aria-modal="true"
aria-label="查看灵感图片"
onClick={() => setSelectedImage(null)}
>
<img
className="block max-h-[92vh] max-w-[92vw] cursor-default object-contain shadow-2xl"
src={selectedImage}
alt="放大的灵感图片"
onClick={(event) => event.stopPropagation()}
/>
</div>,
document.body,
)
: null}
</>
);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

@@ -18,6 +18,7 @@ import {
richTextToAttachments,
richTextToPrompt,
} from './components/RichInputArea/richTextToPrompt';
import InspirationGallery from './InspirationGallery';
import {
type HomeCreationType,
type HomeDraft,
@@ -171,7 +172,11 @@ export default function HomeView({
}
return (
<div className="platform-theme platform-theme--light min-h-screen bg-(image:--platform-body-fill) text-(--platform-text-strong)">
<div
className={`platform-theme platform-theme--light overflow-x-hidden overflow-y-auto bg-(image:--platform-body-fill) pb-12 text-(--platform-text-strong) ${
hasPromo ? 'h-[calc(100vh-32px)]' : 'h-screen'
}`}
>
<section
className={`grid content-start justify-items-center gap-3.5 px-6 pb-4.5 pt-20 max-[760px]:gap-4 max-[760px]:px-3.5 max-[760px]:pb-8.5 max-[760px]:pt-21 ${
hasPromo ? 'pt-28 max-[760px]:pt-21' : ''
@@ -352,7 +357,7 @@ export default function HomeView({
/>
</span>
</header>
<div className="min-h-24 overflow-hidden rounded-lg border border-(--platform-surface-border) bg-(image:--platform-subpanel-fill)" />
<InspirationGallery />
</section>
</div>
);

Some files were not shown because too many files have changed in this diff Show More