mirror of
https://github.com/linsa-io/linsa.git
synced 2026-04-24 17:28:41 +02:00
fix: remove useMemo. causing rerender
This commit is contained in:
@@ -4,7 +4,6 @@ import { atomWithStorage } from "jotai/utils"
|
|||||||
import { Link, useNavigate } from "@tanstack/react-router"
|
import { Link, useNavigate } from "@tanstack/react-router"
|
||||||
import { useAccount } from "@/lib/providers/jazz-provider"
|
import { useAccount } from "@/lib/providers/jazz-provider"
|
||||||
import { cn } from "@/lib/utils"
|
import { cn } from "@/lib/utils"
|
||||||
import { PersonalPage, PersonalPageLists } from "@/lib/schema/personal-page"
|
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import { LaIcon } from "@/components/custom/la-icon"
|
import { LaIcon } from "@/components/custom/la-icon"
|
||||||
import {
|
import {
|
||||||
@@ -48,14 +47,25 @@ const pageShowAtom = atomWithStorage<ShowOption>("pageShow", 5)
|
|||||||
const isExpandedAtom = atomWithStorage("isPageSectionExpanded", true)
|
const isExpandedAtom = atomWithStorage("isPageSectionExpanded", true)
|
||||||
|
|
||||||
export const PageSection: React.FC = () => {
|
export const PageSection: React.FC = () => {
|
||||||
const { me } = useAccount({ root: { personalPages: [] } })
|
const { me } = useAccount({
|
||||||
|
root: {
|
||||||
|
personalPages: [{}],
|
||||||
|
},
|
||||||
|
})
|
||||||
const [sort] = useAtom(pageSortAtom)
|
const [sort] = useAtom(pageSortAtom)
|
||||||
const [show] = useAtom(pageShowAtom)
|
const [show] = useAtom(pageShowAtom)
|
||||||
const [isExpanded, setIsExpanded] = useAtom(isExpandedAtom)
|
const [isExpanded, setIsExpanded] = useAtom(isExpandedAtom)
|
||||||
|
|
||||||
if (!me) return null
|
const pageCount = me?.root.personalPages.length || 0
|
||||||
|
const personalPages = me?.root.personalPages ?? []
|
||||||
const pageCount = me.root.personalPages?.length || 0
|
const sortedPages = [...personalPages]
|
||||||
|
.sort((a, b) => {
|
||||||
|
if (sort === "title") {
|
||||||
|
return (a?.title ?? "").localeCompare(b?.title ?? "")
|
||||||
|
}
|
||||||
|
return (b?.updatedAt?.getTime() ?? 0) - (a?.updatedAt?.getTime() ?? 0)
|
||||||
|
})
|
||||||
|
.slice(0, show === 0 ? personalPages.length : show)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-px py-2">
|
<div className="flex flex-col gap-px py-2">
|
||||||
@@ -65,11 +75,40 @@ export const PageSection: React.FC = () => {
|
|||||||
onToggle={() => setIsExpanded(!isExpanded)}
|
onToggle={() => setIsExpanded(!isExpanded)}
|
||||||
/>
|
/>
|
||||||
{isExpanded && (
|
{isExpanded && (
|
||||||
<PageList
|
<div className="flex flex-col gap-px">
|
||||||
personalPages={me.root.personalPages}
|
{sortedPages.map((page) => (
|
||||||
sort={sort}
|
<Link
|
||||||
show={show}
|
key={page.id}
|
||||||
/>
|
to="/pages/$pageId"
|
||||||
|
params={{ pageId: page.id }}
|
||||||
|
className={cn(
|
||||||
|
"group/p cursor-default text-[var(--less-foreground)]",
|
||||||
|
"relative flex h-[30px] w-full items-center gap-2 rounded-md px-1.5 text-sm font-medium hover:bg-[var(--item-hover)]",
|
||||||
|
)}
|
||||||
|
activeOptions={{ exact: true }}
|
||||||
|
activeProps={{
|
||||||
|
className:
|
||||||
|
"bg-[var(--item-active)] data-[status='active']:hover:bg-[var(--item-active)]",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{({ isActive }) => (
|
||||||
|
<div className="flex max-w-full flex-1 items-center gap-1.5 truncate">
|
||||||
|
<LaIcon
|
||||||
|
name="File"
|
||||||
|
className={cn(
|
||||||
|
"flex-shrink-0 group-hover/p:text-foreground",
|
||||||
|
{
|
||||||
|
"text-foreground": isActive,
|
||||||
|
"text-muted-foreground": !isActive,
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<p className="truncate">{page.title || "Untitled"}</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@@ -162,68 +201,6 @@ const NewPageButton: React.FC = () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PageListProps {
|
|
||||||
personalPages: PersonalPageLists
|
|
||||||
sort: SortOption
|
|
||||||
show: ShowOption
|
|
||||||
}
|
|
||||||
|
|
||||||
const PageList: React.FC<PageListProps> = ({ personalPages, sort, show }) => {
|
|
||||||
const sortedPages = React.useMemo(() => {
|
|
||||||
return [...personalPages]
|
|
||||||
.sort((a, b) => {
|
|
||||||
if (sort === "title") {
|
|
||||||
return (a?.title ?? "").localeCompare(b?.title ?? "")
|
|
||||||
}
|
|
||||||
return (b?.updatedAt?.getTime() ?? 0) - (a?.updatedAt?.getTime() ?? 0)
|
|
||||||
})
|
|
||||||
.slice(0, show === 0 ? personalPages.length : show)
|
|
||||||
}, [personalPages, sort, show])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex flex-col gap-px">
|
|
||||||
{sortedPages.map(
|
|
||||||
(page) => page?.id && <PageListItem key={page.id} page={page} />,
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PageListItemProps {
|
|
||||||
page: PersonalPage
|
|
||||||
}
|
|
||||||
|
|
||||||
const PageListItem: React.FC<PageListItemProps> = ({ page }) => {
|
|
||||||
return (
|
|
||||||
<Link
|
|
||||||
to="/pages/$pageId"
|
|
||||||
params={{ pageId: page.id }}
|
|
||||||
className={cn(
|
|
||||||
"group/p cursor-default text-[var(--less-foreground)]",
|
|
||||||
"relative flex h-[30px] w-full items-center gap-2 rounded-md px-1.5 text-sm font-medium hover:bg-[var(--item-hover)]",
|
|
||||||
)}
|
|
||||||
activeOptions={{ exact: true }}
|
|
||||||
activeProps={{
|
|
||||||
className:
|
|
||||||
"bg-[var(--item-active)] data-[status='active']:hover:bg-[var(--item-active)]",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{({ isActive }) => (
|
|
||||||
<div className="flex max-w-full flex-1 items-center gap-1.5 truncate">
|
|
||||||
<LaIcon
|
|
||||||
name="File"
|
|
||||||
className={cn("flex-shrink-0 group-hover/p:text-foreground", {
|
|
||||||
"text-foreground": isActive,
|
|
||||||
"text-muted-foreground": !isActive,
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
<p className="truncate">{page.title || "Untitled"}</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Link>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
interface SubMenuProps<T> {
|
interface SubMenuProps<T> {
|
||||||
icon: keyof typeof icons
|
icon: keyof typeof icons
|
||||||
label: string
|
label: string
|
||||||
|
|||||||
Reference in New Issue
Block a user