mirror of
https://github.com/linsa-io/linsa.git
synced 2026-01-12 12:20:23 +01:00
wip
This commit is contained in:
@@ -1,23 +1,53 @@
|
||||
"use client"
|
||||
|
||||
import React from "react"
|
||||
import React, { useMemo } from "react"
|
||||
import { TopicDetailHeader } from "./Header"
|
||||
import { TopicSections } from "./partials/topic-sections"
|
||||
import { useLinkNavigation } from "./use-link-navigation"
|
||||
import { useTopicData } from "@/hooks/use-topic-data"
|
||||
import { atom } from "jotai"
|
||||
import { useAccount } from "@/lib/providers/jazz-provider"
|
||||
import { useAccount, useCoState } from "@/lib/providers/jazz-provider"
|
||||
import { Link, Topic } from "@/lib/schema"
|
||||
import { PublicGlobalGroup } from "@/lib/schema/master/public-group"
|
||||
import { ID } from "jazz-tools"
|
||||
import { LinkItem } from "./partials/link-item"
|
||||
|
||||
interface TopicDetailRouteProps {
|
||||
topicName: string
|
||||
}
|
||||
|
||||
export const openPopoverForIdAtom = atom<string | null>(null)
|
||||
const GLOBAL_GROUP_ID = process.env.NEXT_PUBLIC_JAZZ_GLOBAL_GROUP as ID<PublicGlobalGroup>
|
||||
|
||||
export function TopicDetailRoute({ topicName }: TopicDetailRouteProps) {
|
||||
const { me } = useAccount({ root: { personalLinks: [] } })
|
||||
const { topic, allLinks } = useTopicData(topicName)
|
||||
const { activeIndex, setActiveIndex, containerRef, linkRefs } = useLinkNavigation(allLinks)
|
||||
|
||||
// const { topic, allLinks, transformedData } = useTopicData(topicName, me)
|
||||
|
||||
// const findTopic = useMemo(() => me && Topic.findUnique({ topicName }, GLOBAL_GROUP_ID, me), [me])
|
||||
// const topic = useCoState(Topic, findTopic, { latestGlobalGuide: { sections: [{ links: [] }] } })
|
||||
const topic = useCoState(Topic, "co_z729EvE8fQEgMGNGaR4HKa1Jfir" as ID<Topic>, {})
|
||||
|
||||
const transformedData = useMemo(() => {
|
||||
if (!topic?.latestGlobalGuide?.sections) return []
|
||||
|
||||
return topic.latestGlobalGuide.sections.flatMap(section => [
|
||||
{ type: "section", data: section },
|
||||
...(section?.links?.filter(link => !!link?.url).map(link => ({ type: "link", data: link })) || [])
|
||||
])
|
||||
}, [topic?.latestGlobalGuide?.sections])
|
||||
|
||||
// console.log({ transformedData}, "transformedData")
|
||||
|
||||
// const allLinks = useMemo(() => {
|
||||
// if (!topic?.latestGlobalGuide?.sections) return []
|
||||
|
||||
// return topic.latestGlobalGuide.sections.flatMap(
|
||||
// section => section?.links?.filter((link): link is Link => !!link?.url) ?? []
|
||||
// )
|
||||
// }, [topic?.latestGlobalGuide?.sections])
|
||||
|
||||
// const { activeIndex, setActiveIndex, containerRef, linkRefs } = useLinkNavigation(allLinks)
|
||||
|
||||
if (!topic || !me) {
|
||||
return null
|
||||
@@ -26,7 +56,7 @@ export function TopicDetailRoute({ topicName }: TopicDetailRouteProps) {
|
||||
return (
|
||||
<div className="flex h-full flex-auto flex-col">
|
||||
<TopicDetailHeader topic={topic} />
|
||||
<TopicSections
|
||||
{/* <TopicSections
|
||||
topic={topic}
|
||||
sections={topic.latestGlobalGuide?.sections}
|
||||
activeIndex={activeIndex}
|
||||
@@ -35,7 +65,45 @@ export function TopicDetailRoute({ topicName }: TopicDetailRouteProps) {
|
||||
containerRef={containerRef}
|
||||
me={me}
|
||||
personalLinks={me.root.personalLinks}
|
||||
/>
|
||||
/> */}
|
||||
|
||||
<div className="flex w-full flex-1 flex-col overflow-y-auto [scrollbar-gutter:stable]">
|
||||
<div tabIndex={-1} className="outline-none">
|
||||
<div className="flex flex-1 flex-col gap-4" role="listbox" aria-label="Topic sections">
|
||||
{transformedData?.map((data, index) =>
|
||||
data.type === "section" ? (
|
||||
<Section
|
||||
key={index}
|
||||
section={data.data}
|
||||
// key={sectionIndex}
|
||||
// topic={topic}
|
||||
// section={section}
|
||||
// activeIndex={activeIndex}
|
||||
// setActiveIndex={setActiveIndex}
|
||||
// startIndex={sections.slice(0, sectionIndex).reduce((acc, s) => acc + (s?.links?.length || 0), 0)}
|
||||
// linkRefs={linkRefs}
|
||||
// me={me}
|
||||
// personalLinks={personalLinks}
|
||||
/>
|
||||
) : (
|
||||
<LinkItem
|
||||
key={index}
|
||||
link={link}
|
||||
topic={topic}
|
||||
isActive={activeIndex === startIndex + index}
|
||||
index={startIndex + index}
|
||||
setActiveIndex={setActiveIndex}
|
||||
ref={el => {
|
||||
linkRefs.current[startIndex + index] = el
|
||||
}}
|
||||
me={me}
|
||||
personalLinks={personalLinks}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ export const LinkItem = React.memo(
|
||||
toast.success("Link learning state updated", defaultToast)
|
||||
}
|
||||
} else {
|
||||
console.log(personalLinks.toJSON(), link.title)
|
||||
const slug = generateUniqueSlug(personalLinks.toJSON(), link.title)
|
||||
const newPersonalLink = PersonalLink.create(
|
||||
{
|
||||
|
||||
@@ -1,3 +1,83 @@
|
||||
// import { useState, useRef, useCallback, useEffect } from "react"
|
||||
// import { Link as LinkSchema, Section as SectionSchema } from "@/lib/schema"
|
||||
// import { ensureUrlProtocol } from "@/lib/utils"
|
||||
|
||||
// interface TransformedDataItem<T> {
|
||||
// type: string
|
||||
// data: T | null
|
||||
// }
|
||||
|
||||
// type TransformedData<S, L> = Array<TransformedDataItem<S> | TransformedDataItem<L>>
|
||||
|
||||
// interface UseLinkNavigationProps<S, L> {
|
||||
// transformedData: TransformedData<S, L>
|
||||
// }
|
||||
|
||||
// export function useLinkNavigation({ transformedData }: UseLinkNavigationProps<SectionSchema, LinkSchema>) {
|
||||
// const [activeIndex, setActiveIndex] = useState(-1)
|
||||
// const containerRef = useRef<HTMLDivElement>(null)
|
||||
// const linkRefs = useRef<(HTMLLIElement | null)[]>([])
|
||||
|
||||
// const allLinks = transformedData.filter(
|
||||
// (item): item is TransformedDataItem<LinkSchema> => item.type === "link" && item.data !== null
|
||||
// )
|
||||
|
||||
// const scrollToLink = useCallback((index: number) => {
|
||||
// if (linkRefs.current[index] && containerRef.current) {
|
||||
// const linkElement = linkRefs.current[index]
|
||||
// const container = containerRef.current
|
||||
|
||||
// const linkRect = linkElement?.getBoundingClientRect()
|
||||
// const containerRect = container.getBoundingClientRect()
|
||||
|
||||
// if (linkRect && containerRect) {
|
||||
// if (linkRect.bottom > containerRect.bottom) {
|
||||
// container.scrollTop += linkRect.bottom - containerRect.bottom
|
||||
// } else if (linkRect.top < containerRect.top) {
|
||||
// container.scrollTop -= containerRect.top - linkRect.top
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }, [])
|
||||
|
||||
// const handleKeyDown = useCallback(
|
||||
// (e: KeyboardEvent) => {
|
||||
// if (e.key === "ArrowDown") {
|
||||
// e.preventDefault()
|
||||
// setActiveIndex(prevIndex => {
|
||||
// const newIndex = (prevIndex + 1) % allLinks.length
|
||||
// scrollToLink(newIndex)
|
||||
// return newIndex
|
||||
// })
|
||||
// } else if (e.key === "ArrowUp") {
|
||||
// e.preventDefault()
|
||||
// setActiveIndex(prevIndex => {
|
||||
// const newIndex = (prevIndex - 1 + allLinks.length) % allLinks.length
|
||||
// scrollToLink(newIndex)
|
||||
// return newIndex
|
||||
// })
|
||||
// } else if (e.key === "Enter" && activeIndex !== -1) {
|
||||
// const linkItem = allLinks[activeIndex]
|
||||
// if (linkItem && linkItem.data) {
|
||||
// window.open(ensureUrlProtocol(linkItem.data.url), "_blank")
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// [activeIndex, allLinks, scrollToLink]
|
||||
// )
|
||||
|
||||
// useEffect(() => {
|
||||
// window.addEventListener("keydown", handleKeyDown)
|
||||
// return () => window.removeEventListener("keydown", handleKeyDown)
|
||||
// }, [handleKeyDown])
|
||||
|
||||
// useEffect(() => {
|
||||
// linkRefs.current = linkRefs.current.slice(0, allLinks.length)
|
||||
// }, [allLinks])
|
||||
|
||||
// return { activeIndex, setActiveIndex, containerRef, linkRefs }
|
||||
// }
|
||||
|
||||
import { useState, useRef, useCallback, useEffect } from "react"
|
||||
import { Link as LinkSchema } from "@/lib/schema"
|
||||
import { ensureUrlProtocol } from "@/lib/utils"
|
||||
|
||||
Reference in New Issue
Block a user