diff --git a/src/app/(app)/(home)/page.tsx b/src/app/(app)/(home)/page.tsx
index f0137d2586..32c2c49f44 100644
--- a/src/app/(app)/(home)/page.tsx
+++ b/src/app/(app)/(home)/page.tsx
@@ -16,8 +16,10 @@ import { PeekLink } from '~/components/modules/peek/PeekLink'
import { PostMetaBar } from '~/components/modules/post'
import { MotionButtonBase } from '~/components/ui/button'
import { RelativeTime } from '~/components/ui/relative-time'
-import { BottomToUpTransitionView } from '~/components/ui/transition/BottomToUpTransitionView'
-import { TextUpTransitionView } from '~/components/ui/transition/TextUpTransitionView'
+import {
+ BottomToUpTransitionView,
+ TextUpTransitionView,
+} from '~/components/ui/transition'
import {
microReboundPreset,
softBouncePreset,
diff --git a/src/app/(app)/(note-topic)/notes/(topic-detail)/topics/[slug]/page.tsx b/src/app/(app)/(note-topic)/notes/(topic-detail)/topics/[slug]/page.tsx
index 0d52c21122..643bde8b64 100644
--- a/src/app/(app)/(note-topic)/notes/(topic-detail)/topics/[slug]/page.tsx
+++ b/src/app/(app)/(note-topic)/notes/(topic-detail)/topics/[slug]/page.tsx
@@ -7,8 +7,10 @@ import { useParams } from 'next/navigation'
import { LoadMoreIndicator } from '~/components/modules/shared/LoadMoreIndicator'
import { TimelineList } from '~/components/ui/list/TimelineList'
import { Loading } from '~/components/ui/loading'
-import { BottomToUpSoftScaleTransitionView } from '~/components/ui/transition/BottomToUpSoftScaleTransitionView'
-import { BottomToUpTransitionView } from '~/components/ui/transition/BottomToUpTransitionView'
+import {
+ BottomToUpSoftScaleTransitionView,
+ BottomToUpTransitionView,
+} from '~/components/ui/transition'
import { apiClient } from '~/lib/request'
import { routeBuilder, Routes } from '~/lib/route-builder'
diff --git a/src/app/(app)/(note-topic)/notes/topics/page.tsx b/src/app/(app)/(note-topic)/notes/topics/page.tsx
index 39e5f66f40..8392e18801 100644
--- a/src/app/(app)/(note-topic)/notes/topics/page.tsx
+++ b/src/app/(app)/(note-topic)/notes/topics/page.tsx
@@ -4,8 +4,10 @@ import { useQuery } from '@tanstack/react-query'
import Link from 'next/link'
import { TimelineList } from '~/components/ui/list/TimelineList'
-import { BottomToUpSoftScaleTransitionView } from '~/components/ui/transition/BottomToUpSoftScaleTransitionView'
-import { BottomToUpTransitionView } from '~/components/ui/transition/BottomToUpTransitionView'
+import {
+ BottomToUpSoftScaleTransitionView,
+ BottomToUpTransitionView,
+} from '~/components/ui/transition'
import { routeBuilder, Routes } from '~/lib/route-builder'
import { topicsQuery } from './query'
diff --git a/src/app/(app)/(page-detail)/[slug]/layout.tsx b/src/app/(app)/(page-detail)/[slug]/layout.tsx
index bba546e396..d3f36e1655 100644
--- a/src/app/(app)/(page-detail)/[slug]/layout.tsx
+++ b/src/app/(app)/(page-detail)/[slug]/layout.tsx
@@ -9,8 +9,10 @@ import {
} from '~/components/modules/activity'
import { CommentAreaRootLazy } from '~/components/modules/comment'
import { TocFAB } from '~/components/modules/toc/TocFAB'
-import { BottomToUpSoftScaleTransitionView } from '~/components/ui/transition/BottomToUpSoftScaleTransitionView'
-import { BottomToUpTransitionView } from '~/components/ui/transition/BottomToUpTransitionView'
+import {
+ BottomToUpSoftScaleTransitionView,
+ BottomToUpTransitionView,
+} from '~/components/ui/transition'
import { OnlyMobile } from '~/components/ui/viewport/OnlyMobile'
import { attachUAAndRealIp } from '~/lib/attach-ua'
import { getOgUrl } from '~/lib/helper.server'
diff --git a/src/app/(app)/categories/[slug]/page.tsx b/src/app/(app)/categories/[slug]/page.tsx
index 2710006c90..76a4dd0019 100644
--- a/src/app/(app)/categories/[slug]/page.tsx
+++ b/src/app/(app)/categories/[slug]/page.tsx
@@ -6,8 +6,10 @@ import { useParams } from 'next/navigation'
import { BackToTopFAB } from '~/components/ui/fab'
import { TimelineList } from '~/components/ui/list/TimelineList'
-import { BottomToUpSoftScaleTransitionView } from '~/components/ui/transition/BottomToUpSoftScaleTransitionView'
-import { BottomToUpTransitionView } from '~/components/ui/transition/BottomToUpTransitionView'
+import {
+ BottomToUpSoftScaleTransitionView,
+ BottomToUpTransitionView,
+} from '~/components/ui/transition'
import { routeBuilder, Routes } from '~/lib/route-builder'
import { getPageBySlugQuery } from './query'
diff --git a/src/app/(app)/friends/page.tsx b/src/app/(app)/friends/page.tsx
index 9cc07c5773..4255d19e81 100644
--- a/src/app/(app)/friends/page.tsx
+++ b/src/app/(app)/friends/page.tsx
@@ -18,7 +18,7 @@ import { BackToTopFAB } from '~/components/ui/fab'
import { Form, FormInput } from '~/components/ui/form'
import { Loading } from '~/components/ui/loading'
import { useModalStack } from '~/components/ui/modal'
-import { BottomToUpTransitionView } from '~/components/ui/transition/BottomToUpTransitionView'
+import { BottomToUpTransitionView } from '~/components/ui/transition'
import { shuffle } from '~/lib/lodash'
import { apiClient, getErrorMessageFromRequestError } from '~/lib/request'
import { toast } from '~/lib/toast'
diff --git a/src/app/(app)/notes/[id]/layout.tsx b/src/app/(app)/notes/[id]/layout.tsx
index 5807256237..9999a371ed 100644
--- a/src/app/(app)/notes/[id]/layout.tsx
+++ b/src/app/(app)/notes/[id]/layout.tsx
@@ -7,7 +7,7 @@ import { CommentAreaRootLazy } from '~/components/modules/comment'
import { NoteFontSettingFab } from '~/components/modules/note/NoteFontFab'
import { NoteMainContainer } from '~/components/modules/note/NoteMainContainer'
import { TocFAB } from '~/components/modules/toc/TocFAB'
-import { BottomToUpSoftScaleTransitionView } from '~/components/ui/transition/BottomToUpSoftScaleTransitionView'
+import { BottomToUpSoftScaleTransitionView } from '~/components/ui/transition'
import { OnlyMobile } from '~/components/ui/viewport/OnlyMobile'
import { getOgUrl } from '~/lib/helper.server'
import { getSummaryFromMd } from '~/lib/markdown'
diff --git a/src/app/(app)/posts/(post-detail)/[category]/[slug]/layout.tsx b/src/app/(app)/posts/(post-detail)/[category]/[slug]/layout.tsx
index c46f7292c2..f13d1d1c05 100644
--- a/src/app/(app)/posts/(post-detail)/[category]/[slug]/layout.tsx
+++ b/src/app/(app)/posts/(post-detail)/[category]/[slug]/layout.tsx
@@ -5,8 +5,10 @@ import type { PageParams } from './api'
import { buildRoomName, RoomProvider } from '~/components/modules/activity'
import { CommentAreaRootLazy } from '~/components/modules/comment'
import { TocFAB } from '~/components/modules/toc/TocFAB'
-import { BottomToUpSoftScaleTransitionView } from '~/components/ui/transition/BottomToUpSoftScaleTransitionView'
-import { BottomToUpTransitionView } from '~/components/ui/transition/BottomToUpTransitionView'
+import {
+ BottomToUpSoftScaleTransitionView,
+ BottomToUpTransitionView,
+} from '~/components/ui/transition'
import { OnlyMobile } from '~/components/ui/viewport/OnlyMobile'
import { getOgUrl } from '~/lib/helper.server'
import { getSummaryFromMd } from '~/lib/markdown'
diff --git a/src/app/(app)/posts/page.tsx b/src/app/(app)/posts/page.tsx
index dadc72d345..6f11ac2f04 100644
--- a/src/app/(app)/posts/page.tsx
+++ b/src/app/(app)/posts/page.tsx
@@ -7,7 +7,7 @@ import { PostPagination } from '~/components/modules/post/PostPagination'
import { NothingFound } from '~/components/modules/shared/NothingFound'
import { SearchFAB } from '~/components/modules/shared/SearchFAB'
import { BackToTopFAB } from '~/components/ui/fab'
-import { BottomToUpTransitionView } from '~/components/ui/transition/BottomToUpTransitionView'
+import { BottomToUpTransitionView } from '~/components/ui/transition'
import { OnlyDesktop } from '~/components/ui/viewport'
import { apiClient } from '~/lib/request'
diff --git a/src/app/(app)/projects/page.tsx b/src/app/(app)/projects/page.tsx
index f4385bc408..b6ec6d90d7 100644
--- a/src/app/(app)/projects/page.tsx
+++ b/src/app/(app)/projects/page.tsx
@@ -6,7 +6,7 @@ import { GitHubBrandIcon } from '~/components/icons/platform/GitHubBrandIcon'
import { ProjectList } from '~/components/modules/project/ProjectList'
import { NothingFound } from '~/components/modules/shared/NothingFound'
import { Loading } from '~/components/ui/loading'
-import { BottomToUpTransitionView } from '~/components/ui/transition/BottomToUpTransitionView'
+import { BottomToUpTransitionView } from '~/components/ui/transition'
import { noopArr } from '~/lib/noop'
import { apiClient } from '~/lib/request'
import { useAggregationSelector } from '~/providers/root/aggregation-data-provider'
diff --git a/src/app/(app)/says/page.tsx b/src/app/(app)/says/page.tsx
index 7da22fd581..5d487c47bf 100644
--- a/src/app/(app)/says/page.tsx
+++ b/src/app/(app)/says/page.tsx
@@ -1,59 +1,19 @@
'use client'
-import { useInfiniteQuery } from '@tanstack/react-query'
-import { memo, useMemo } from 'react'
-import { m } from 'framer-motion'
-import Markdown from 'markdown-to-jsx'
-import type { SayModel } from '@mx-space/api-client'
-import type { MarkdownToJSX } from 'markdown-to-jsx'
-
-import { useIsMobile } from '~/atoms/hooks'
-import { LoadMoreIndicator } from '~/components/modules/shared/LoadMoreIndicator'
+import { useSayListQuery } from '~/components/modules/say/hooks'
+import { SayMasonry } from '~/components/modules/say/SayMasonry'
import { NothingFound } from '~/components/modules/shared/NothingFound'
-import { Loading } from '~/components/ui/loading'
-import { Masonry } from '~/components/ui/masonry'
-import { RelativeTime } from '~/components/ui/relative-time'
-import { BottomToUpSoftScaleTransitionView } from '~/components/ui/transition/BottomToUpSoftScaleTransitionView'
-import { BottomToUpTransitionView } from '~/components/ui/transition/BottomToUpTransitionView'
-import { useIsDark } from '~/hooks/common/use-is-dark'
-import { addAlphaToHSL, getColorScheme, stringToHue } from '~/lib/color'
-import { apiClient } from '~/lib/request'
-
-import { sayQueryKey } from './query'
+import { FullPageLoading } from '~/components/ui/loading'
export default function Page() {
- const { fetchNextPage, hasNextPage, data, isLoading } = useInfiniteQuery({
- queryKey: sayQueryKey,
- queryFn: async ({ pageParam }) => {
- const data = await apiClient.say.getAllPaginated(pageParam)
- return data
- },
- initialPageParam: 1,
- getNextPageParam: (lastPage) =>
- lastPage.pagination.hasNextPage
- ? lastPage.pagination.currentPage + 1
- : undefined,
- })
-
- const isMobile = useIsMobile()
+ const { data, isLoading } = useSayListQuery()
if (isLoading) {
- return