mirror of
https://github.com/linsa-io/linsa.git
synced 2026-01-12 12:20:23 +01:00
chore: preload nested deps
This commit is contained in:
@@ -17,7 +17,7 @@ export const openPopoverForIdAtom = atom<string | null>(null)
|
||||
|
||||
export function TopicDetailComponent() {
|
||||
const params = useParams({ from: "/_layout/_pages/(topic)/$" })
|
||||
const { me } = useAccountOrGuest({ root: { personalLinks: [] } })
|
||||
const { me } = useAccountOrGuest({ root: { personalLinks: [{}] } })
|
||||
|
||||
const topicID = React.useMemo(
|
||||
() =>
|
||||
|
||||
@@ -29,9 +29,9 @@ export const TopicDetailHeader = function TopicDetailHeader({
|
||||
const isMobile = useMedia("(max-width: 770px)")
|
||||
const { me } = useAccountOrGuest({
|
||||
root: {
|
||||
topicsWantToLearn: [],
|
||||
topicsLearning: [],
|
||||
topicsLearned: [],
|
||||
topicsWantToLearn: [{}],
|
||||
topicsLearning: [{}],
|
||||
topicsLearned: [{}],
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ export function TopicDetailList({
|
||||
activeIndex,
|
||||
setActiveIndex,
|
||||
}: TopicDetailListProps) {
|
||||
const { me } = useAccountOrGuest({ root: { personalLinks: [] } })
|
||||
const { me } = useAccountOrGuest({ root: { personalLinks: [{}] } })
|
||||
const personalLinks =
|
||||
!me || me._type === "Anonymous" ? undefined : me.root.personalLinks
|
||||
|
||||
|
||||
@@ -2,12 +2,24 @@ import { createFileRoute, Outlet, redirect } from "@tanstack/react-router"
|
||||
|
||||
export const Route = createFileRoute("/_layout/_pages/_protected")({
|
||||
beforeLoad: async ({ context, location }) => {
|
||||
if (!context?.auth?.userId) {
|
||||
// Add extra validation
|
||||
if (!context || !context.auth) {
|
||||
throw redirect({
|
||||
to: "/sign-in/$",
|
||||
search: { redirect_url: location.pathname },
|
||||
})
|
||||
}
|
||||
|
||||
const auth = await context.auth
|
||||
|
||||
if (!auth?.userId) {
|
||||
throw redirect({
|
||||
to: "/sign-in/$",
|
||||
search: { redirect_url: location.pathname },
|
||||
})
|
||||
}
|
||||
|
||||
return context
|
||||
},
|
||||
component: () => <Outlet />,
|
||||
})
|
||||
|
||||
@@ -26,7 +26,7 @@ interface Question {
|
||||
|
||||
function CommunityTopicComponent() {
|
||||
const { topicName } = Route.useParams()
|
||||
const { me } = useAccountOrGuest({ root: { personalLinks: [] } })
|
||||
const { me } = useAccountOrGuest()
|
||||
const topicID = useMemo(
|
||||
() => me && Topic.findUnique({ topicName }, JAZZ_GLOBAL_GROUP_ID, me),
|
||||
[topicName, me],
|
||||
|
||||
@@ -143,7 +143,7 @@ export const LinkForm: React.FC<LinkFormProps> = ({
|
||||
|
||||
const [isFetching, setIsFetching] = React.useState(false)
|
||||
const [urlFetched, setUrlFetched] = React.useState<string | null>(null)
|
||||
const { me } = useAccount()
|
||||
const { me } = useAccount({ root: { personalLinks: [{}] } })
|
||||
const selectedLink = useCoState(PersonalLink, personalLink?.id)
|
||||
|
||||
const form = useForm<LinkFormValues>({
|
||||
|
||||
@@ -80,9 +80,9 @@ const StepItem = ({
|
||||
function OnboardingComponent() {
|
||||
const { me } = useAccount({
|
||||
root: {
|
||||
personalPages: [],
|
||||
personalLinks: [],
|
||||
topicsWantToLearn: [],
|
||||
personalPages: [{}],
|
||||
personalLinks: [{}],
|
||||
topicsWantToLearn: [{}],
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import * as React from "react"
|
||||
import { createFileRoute, useNavigate } from "@tanstack/react-router"
|
||||
import { ID } from "jazz-tools"
|
||||
import { LaAccount, PersonalPage } from "@/lib/schema"
|
||||
import { PersonalPage } from "@/lib/schema"
|
||||
import { Content, EditorContent, useEditor } from "@tiptap/react"
|
||||
import { useAccount, useCoState } from "@/lib/providers/jazz-provider"
|
||||
import { useCoState } from "@/lib/providers/jazz-provider"
|
||||
import { EditorView } from "@tiptap/pm/view"
|
||||
import { Editor } from "@tiptap/core"
|
||||
import { generateUniqueSlug } from "@/lib/utils"
|
||||
@@ -29,17 +29,10 @@ const TITLE_PLACEHOLDER = "Untitled"
|
||||
|
||||
function PageDetailComponent() {
|
||||
const { pageId } = Route.useParams()
|
||||
const { me } = useAccount({
|
||||
root: {
|
||||
personalPages: [
|
||||
{
|
||||
topic: {},
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
const isMobile = useMedia("(max-width: 770px)")
|
||||
const page = useCoState(PersonalPage, pageId as ID<PersonalPage>)
|
||||
const page = useCoState(PersonalPage, pageId as ID<PersonalPage>, {
|
||||
topic: {},
|
||||
})
|
||||
|
||||
const navigate = useNavigate()
|
||||
const { deletePage } = usePageActions()
|
||||
@@ -55,13 +48,13 @@ function PageDetailComponent() {
|
||||
confirmButton: { variant: "destructive" },
|
||||
})
|
||||
|
||||
if (result && me?.root.personalPages) {
|
||||
deletePage(me, pageId as ID<PersonalPage>)
|
||||
if (result) {
|
||||
deletePage(pageId as ID<PersonalPage>)
|
||||
navigate({ to: "/pages" })
|
||||
}
|
||||
}, [confirm, deletePage, me, pageId, navigate])
|
||||
}, [confirm, deletePage, pageId, navigate])
|
||||
|
||||
if (!page || !me) return null
|
||||
if (!page) return null
|
||||
|
||||
return (
|
||||
<div className="absolute inset-0 flex flex-row overflow-hidden">
|
||||
@@ -72,7 +65,7 @@ function PageDetailComponent() {
|
||||
handleDelete={handleDelete}
|
||||
isMobile={isMobile}
|
||||
/>
|
||||
<DetailPageForm page={page} me={me} />
|
||||
<DetailPageForm page={page} />
|
||||
</div>
|
||||
|
||||
{!isMobile && (
|
||||
@@ -132,29 +125,11 @@ const SidebarActions = ({
|
||||
|
||||
SidebarActions.displayName = "SidebarActions"
|
||||
|
||||
const DetailPageForm = ({
|
||||
page,
|
||||
me,
|
||||
}: {
|
||||
page: PersonalPage
|
||||
me: LaAccount
|
||||
}) => {
|
||||
const DetailPageForm = ({ page }: { page: PersonalPage }) => {
|
||||
const titleEditorRef = React.useRef<Editor | null>(null)
|
||||
const contentEditorRef = React.useRef<Editor | null>(null)
|
||||
const [isInitialSync, setIsInitialSync] = React.useState(true)
|
||||
|
||||
// const { id: pageId, title: pageTitle } = page
|
||||
|
||||
// React.useEffect(() => {
|
||||
// if (!pageId) return
|
||||
|
||||
// if (!pageTitle && titleEditorRef.current) {
|
||||
// titleEditorRef.current.commands.focus()
|
||||
// } else if (contentEditorRef.current) {
|
||||
// contentEditorRef.current.commands.focus()
|
||||
// }
|
||||
// }, [pageId, pageTitle])
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!page) return
|
||||
|
||||
@@ -293,17 +268,25 @@ const DetailPageForm = ({
|
||||
onUpdate: ({ editor }) => handleUpdateTitle(editor),
|
||||
})
|
||||
|
||||
const { content: pageContent, title: pageTitle } = page
|
||||
|
||||
const handleCreate = React.useCallback(
|
||||
({ editor }: { editor: Editor }) => {
|
||||
contentEditorRef.current = editor
|
||||
|
||||
if (page.content) {
|
||||
editor.commands.setContent(page.content as Content)
|
||||
if (pageContent) {
|
||||
editor.commands.setContent(pageContent as Content)
|
||||
}
|
||||
|
||||
setIsInitialSync(false)
|
||||
|
||||
if (!pageTitle && titleEditorRef.current) {
|
||||
titleEditorRef.current.commands.focus()
|
||||
} else if (contentEditorRef.current) {
|
||||
contentEditorRef.current.commands.focus()
|
||||
}
|
||||
},
|
||||
[page.content],
|
||||
[pageContent, pageTitle],
|
||||
)
|
||||
|
||||
return (
|
||||
@@ -312,6 +295,7 @@ const DetailPageForm = ({
|
||||
<form className="flex shrink-0 flex-col">
|
||||
<div className="mb-2 mt-8 py-1.5">
|
||||
<EditorContent
|
||||
key={page.id}
|
||||
editor={titleEditor}
|
||||
className="title-editor no-command grow cursor-text select-text text-2xl font-semibold leading-[calc(1.33333)] tracking-[-0.00625rem]"
|
||||
/>
|
||||
@@ -319,8 +303,7 @@ const DetailPageForm = ({
|
||||
<div className="flex flex-auto flex-col">
|
||||
<div className="relative flex h-full max-w-full grow flex-col items-stretch p-0">
|
||||
<LaEditor
|
||||
me={me}
|
||||
personalPage={page}
|
||||
key={page.id}
|
||||
editorClassName="-mx-3.5 px-3.5 py-2.5 flex-auto focus:outline-none"
|
||||
value={page.content as Content}
|
||||
placeholder="Add content..."
|
||||
|
||||
@@ -5,16 +5,12 @@ import {
|
||||
SidebarToggleButton,
|
||||
} from "@/components/custom/content-header"
|
||||
import { LaIcon } from "@/components/custom/la-icon"
|
||||
import { useAccount } from "@/lib/providers/jazz-provider"
|
||||
import { usePageActions } from "~/hooks/actions/use-page-actions"
|
||||
|
||||
interface PageHeaderProps {}
|
||||
|
||||
export const PageHeader: React.FC<PageHeaderProps> = () => {
|
||||
const { me } = useAccount()
|
||||
const { newPage } = usePageActions()
|
||||
|
||||
if (!me) return null
|
||||
const { createNewPage } = usePageActions()
|
||||
|
||||
return (
|
||||
<ContentHeader>
|
||||
@@ -28,7 +24,7 @@ export const PageHeader: React.FC<PageHeaderProps> = () => {
|
||||
type="button"
|
||||
variant="secondary"
|
||||
className="gap-x-2"
|
||||
onClick={newPage}
|
||||
onClick={createNewPage}
|
||||
>
|
||||
<LaIcon name="Plus" />
|
||||
<span className="hidden md:block">New page</span>
|
||||
|
||||
@@ -26,7 +26,14 @@ const ProfileStats: React.FC<ProfileStatsProps> = ({ number, label }) => {
|
||||
}
|
||||
|
||||
function ProfileComponent() {
|
||||
const account = useAccount()
|
||||
const account = useAccount({
|
||||
profile: {},
|
||||
root: {
|
||||
topicsLearning: [{}],
|
||||
topicsWantToLearn: [{}],
|
||||
topicsLearned: [{}],
|
||||
},
|
||||
})
|
||||
const username = ""
|
||||
const { user } = useUser()
|
||||
const avatarInputRef = React.useRef<HTMLInputElement>(null)
|
||||
|
||||
@@ -82,7 +82,7 @@ export const Route = createFileRoute("/_layout/_pages/_protected/tasks/")({
|
||||
|
||||
function TaskComponent() {
|
||||
const { filter } = Route.useSearch()
|
||||
const { me } = useAccount({ root: { tasks: [] } })
|
||||
const { me } = useAccount({ root: { tasks: [{}] } })
|
||||
const tasks = me?.root.tasks
|
||||
const { deleteTask } = useTaskActions()
|
||||
|
||||
|
||||
@@ -30,7 +30,11 @@ export const TopicItem = React.forwardRef<HTMLAnchorElement, TopicItemProps>(
|
||||
)
|
||||
const navigate = useNavigate()
|
||||
const { me } = useAccount({
|
||||
root: { topicsWantToLearn: [], topicsLearning: [], topicsLearned: [] },
|
||||
root: {
|
||||
topicsWantToLearn: [{}],
|
||||
topicsLearning: [{}],
|
||||
topicsLearned: [{}],
|
||||
},
|
||||
})
|
||||
|
||||
let p: {
|
||||
|
||||
@@ -5,23 +5,13 @@ import { atom } from "jotai"
|
||||
import { useMedia } from "@/hooks/use-media"
|
||||
import { useActiveItemScroll } from "@/hooks/use-active-item-scroll"
|
||||
import { Column } from "@/components/custom/column"
|
||||
import { LaAccount, ListOfTopics, Topic, UserRoot } from "@/lib/schema"
|
||||
import { Topic } from "@/lib/schema"
|
||||
import { LearningStateValue } from "@/lib/constants"
|
||||
import { useKeyDown } from "@/hooks/use-key-down"
|
||||
import { TopicItem } from "./-item"
|
||||
|
||||
interface TopicListProps {}
|
||||
|
||||
interface MainTopicListProps extends TopicListProps {
|
||||
me: {
|
||||
root: {
|
||||
topicsWantToLearn: ListOfTopics
|
||||
topicsLearning: ListOfTopics
|
||||
topicsLearned: ListOfTopics
|
||||
} & UserRoot
|
||||
} & LaAccount
|
||||
}
|
||||
|
||||
export interface PersonalTopic {
|
||||
topic: Topic | null
|
||||
learningState: LearningStateValue
|
||||
@@ -31,15 +21,13 @@ export const topicOpenPopoverForIdAtom = atom<string | null>(null)
|
||||
|
||||
export const TopicList: React.FC<TopicListProps> = () => {
|
||||
const { me } = useAccount({
|
||||
root: { topicsWantToLearn: [], topicsLearning: [], topicsLearned: [] },
|
||||
root: {
|
||||
topicsWantToLearn: [{}],
|
||||
topicsLearning: [{}],
|
||||
topicsLearned: [{}],
|
||||
},
|
||||
})
|
||||
|
||||
if (!me) return null
|
||||
|
||||
return <MainTopicList me={me} />
|
||||
}
|
||||
|
||||
export const MainTopicList: React.FC<MainTopicListProps> = ({ me }) => {
|
||||
const isTablet = useMedia("(max-width: 640px)")
|
||||
const [activeItemIndex, setActiveItemIndex] = React.useState<number | null>(
|
||||
null,
|
||||
@@ -49,21 +37,24 @@ export const MainTopicList: React.FC<MainTopicListProps> = ({ me }) => {
|
||||
>(null)
|
||||
|
||||
const personalTopics = React.useMemo(
|
||||
() => [
|
||||
...me.root.topicsWantToLearn.map((topic) => ({
|
||||
topic,
|
||||
learningState: "wantToLearn" as const,
|
||||
})),
|
||||
...me.root.topicsLearning.map((topic) => ({
|
||||
topic,
|
||||
learningState: "learning" as const,
|
||||
})),
|
||||
...me.root.topicsLearned.map((topic) => ({
|
||||
topic,
|
||||
learningState: "learned" as const,
|
||||
})),
|
||||
],
|
||||
[me.root.topicsWantToLearn, me.root.topicsLearning, me.root.topicsLearned],
|
||||
() =>
|
||||
me
|
||||
? [
|
||||
...me.root.topicsWantToLearn.map((topic) => ({
|
||||
topic,
|
||||
learningState: "wantToLearn" as const,
|
||||
})),
|
||||
...me.root.topicsLearning.map((topic) => ({
|
||||
topic,
|
||||
learningState: "learning" as const,
|
||||
})),
|
||||
...me.root.topicsLearned.map((topic) => ({
|
||||
topic,
|
||||
learningState: "learned" as const,
|
||||
})),
|
||||
]
|
||||
: [],
|
||||
[me],
|
||||
)
|
||||
|
||||
const next = () =>
|
||||
|
||||
@@ -85,9 +85,7 @@ const SearchComponent = () => {
|
||||
pages: PersonalPage[]
|
||||
}>({ topics: [], links: [], pages: [] })
|
||||
|
||||
const { me } = useAccountOrGuest({
|
||||
root: { personalLinks: [{}], personalPages: [{}] },
|
||||
})
|
||||
const { me } = useAccountOrGuest()
|
||||
|
||||
const globalGroup = useCoState(PublicGlobalGroup, JAZZ_GLOBAL_GROUP_ID, {
|
||||
root: {
|
||||
@@ -112,14 +110,14 @@ const SearchComponent = () => {
|
||||
links:
|
||||
me?._type === "Anonymous"
|
||||
? []
|
||||
: me?.root.personalLinks?.filter(
|
||||
: me?.root?.personalLinks?.filter(
|
||||
(link: PersonalLink | null): link is PersonalLink =>
|
||||
link !== null && link.title.toLowerCase().startsWith(value),
|
||||
) || [],
|
||||
pages:
|
||||
me?._type === "Anonymous"
|
||||
? []
|
||||
: me?.root.personalPages.filter(
|
||||
: me?.root?.personalPages?.filter(
|
||||
(page): page is PersonalPage =>
|
||||
page !== null &&
|
||||
page.title !== undefined &&
|
||||
|
||||
Reference in New Issue
Block a user