Skip to content

Commit b1af976

Browse files
Copilotna-trium-144
andcommitted
Move DynamicMdProvider to layout.tsx for sidebar access
Co-authored-by: na-trium-144 <100704180+na-trium-144@users.noreply.github.com>
1 parent d0c4523 commit b1af976

5 files changed

Lines changed: 62 additions & 55 deletions

File tree

app/[docs_id]/dynamicMdContext.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,11 @@ export function useDynamicMdContextOptional() {
2626

2727
export function DynamicMdProvider({
2828
children,
29-
initialContent,
3029
}: {
3130
children: ReactNode;
32-
initialContent: DynamicMarkdownSection[];
3331
}) {
3432
const [dynamicMdContent, setDynamicMdContent] =
35-
useState<DynamicMarkdownSection[]>(initialContent);
33+
useState<DynamicMarkdownSection[]>([]);
3634

3735
return (
3836
<DynamicMdContext.Provider value={{ dynamicMdContent, setDynamicMdContent }}>

app/[docs_id]/page.tsx

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { MarkdownSection, splitMarkdown } from "./splitMarkdown";
66
import pyodideLock from "pyodide/pyodide-lock.json";
77
import { PageContent } from "./pageContent";
88
import { ChatHistoryProvider } from "./chatHistory";
9-
import { DynamicMdProvider } from "./dynamicMdContext";
109
import { getChat } from "@/lib/chatHistory";
1110

1211
export default async function Page({
@@ -53,21 +52,13 @@ export default async function Page({
5352

5453
const initialChatHistories = getChat(docs_id);
5554

56-
const initialDynamicMdContent = (await splitMdContent).map((section, i) => ({
57-
...section,
58-
inView: false,
59-
sectionId: `${docs_id}-${i}`,
60-
}));
61-
6255
return (
6356
<ChatHistoryProvider initialChatHistories={await initialChatHistories}>
64-
<DynamicMdProvider initialContent={initialDynamicMdContent}>
65-
<PageContent
66-
documentContent={await mdContent}
67-
splitMdContent={await splitMdContent}
68-
docs_id={docs_id}
69-
/>
70-
</DynamicMdProvider>
57+
<PageContent
58+
documentContent={await mdContent}
59+
splitMdContent={await splitMdContent}
60+
docs_id={docs_id}
61+
/>
7162
</ChatHistoryProvider>
7263
);
7364
}

app/[docs_id]/pageContent.tsx

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,28 @@ interface PageContentProps {
2020
docs_id: string;
2121
}
2222
export function PageContent(props: PageContentProps) {
23-
const { dynamicMdContent, setDynamicMdContent } = useDynamicMdContext();
23+
const { setDynamicMdContent } = useDynamicMdContext();
24+
25+
// SSR用のローカルstate
26+
const [localDynamicMdContent, setLocalDynamicMdContent] = useState<
27+
DynamicMarkdownSection[]
28+
>(
29+
props.splitMdContent.map((section, i) => ({
30+
...section,
31+
inView: false,
32+
sectionId: `${props.docs_id}-${i}`,
33+
}))
34+
);
2435

2536
useEffect(() => {
26-
// props.splitMdContentが変わったときにdynamicMdContentを更新
27-
setDynamicMdContent(
28-
props.splitMdContent.map((section, i) => ({
29-
...section,
30-
inView: false,
31-
sectionId: `${props.docs_id}-${i}`,
32-
}))
33-
);
37+
// props.splitMdContentが変わったときにローカルstateとcontextの両方を更新
38+
const newContent = props.splitMdContent.map((section, i) => ({
39+
...section,
40+
inView: false,
41+
sectionId: `${props.docs_id}-${i}`,
42+
}));
43+
setLocalDynamicMdContent(newContent);
44+
setDynamicMdContent(newContent);
3445
}, [props.splitMdContent, props.docs_id, setDynamicMdContent]);
3546

3647
const sectionRefs = useRef<Array<HTMLDivElement | null>>([]);
@@ -41,7 +52,7 @@ export function PageContent(props: PageContentProps) {
4152

4253
useEffect(() => {
4354
const handleScroll = () => {
44-
setDynamicMdContent((prevDynamicMdContent) => {
55+
const updateContent = (prevDynamicMdContent: DynamicMarkdownSection[]) => {
4556
const dynMdContent = prevDynamicMdContent.slice(); // Reactの変更検知のために新しい配列を作成
4657
for (let i = 0; i < sectionRefs.current.length; i++) {
4758
if (sectionRefs.current.at(i) && dynMdContent.at(i)) {
@@ -51,7 +62,11 @@ export function PageContent(props: PageContentProps) {
5162
}
5263
}
5364
return dynMdContent;
54-
});
65+
};
66+
67+
// ローカルstateとcontextの両方を更新
68+
setLocalDynamicMdContent(updateContent);
69+
setDynamicMdContent(updateContent);
5570
};
5671
window.addEventListener("scroll", handleScroll);
5772
handleScroll();
@@ -71,7 +86,7 @@ export function PageContent(props: PageContentProps) {
7186
gridTemplateColumns: `1fr auto`,
7287
}}
7388
>
74-
{dynamicMdContent.map((section, index) => (
89+
{localDynamicMdContent.map((section, index) => (
7590
<>
7691
<div
7792
className="max-w-200"
@@ -127,7 +142,7 @@ export function PageContent(props: PageContentProps) {
127142
<div className="fixed bottom-4 right-4 left-4 lg:left-84 z-20">
128143
<ChatForm
129144
documentContent={props.documentContent}
130-
sectionContent={dynamicMdContent}
145+
sectionContent={localDynamicMdContent}
131146
docs_id={props.docs_id}
132147
close={() => setIsFormVisible(false)}
133148
/>

app/layout.tsx

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { PyodideProvider } from "./terminal/python/pyodide";
99
import { WandboxProvider } from "./terminal/wandbox/wandbox";
1010
import { EmbedContextProvider } from "./terminal/embedContext";
1111
import { AutoAnonymousLogin } from "./accountMenu";
12+
import { DynamicMdProvider } from "./[docs_id]/dynamicMdContext";
1213

1314
export const metadata: Metadata = {
1415
title: "Create Next App",
@@ -22,25 +23,27 @@ export default function RootLayout({
2223
<html lang="ja">
2324
<body className="w-screen h-screen">
2425
<AutoAnonymousLogin />
25-
<div className="drawer lg:drawer-open">
26-
<input id="drawer-toggle" type="checkbox" className="drawer-toggle" />
27-
<div className="drawer-content flex flex-col">
28-
<Navbar />
29-
<EmbedContextProvider>
30-
<PyodideProvider>
31-
<WandboxProvider>{children}</WandboxProvider>
32-
</PyodideProvider>
33-
</EmbedContextProvider>
26+
<DynamicMdProvider>
27+
<div className="drawer lg:drawer-open">
28+
<input id="drawer-toggle" type="checkbox" className="drawer-toggle" />
29+
<div className="drawer-content flex flex-col">
30+
<Navbar />
31+
<EmbedContextProvider>
32+
<PyodideProvider>
33+
<WandboxProvider>{children}</WandboxProvider>
34+
</PyodideProvider>
35+
</EmbedContextProvider>
36+
</div>
37+
<div className="drawer-side shadow-md z-50">
38+
<label
39+
htmlFor="drawer-toggle"
40+
aria-label="close sidebar"
41+
className="drawer-overlay"
42+
/>
43+
<Sidebar />
44+
</div>
3445
</div>
35-
<div className="drawer-side shadow-md z-50">
36-
<label
37-
htmlFor="drawer-toggle"
38-
aria-label="close sidebar"
39-
className="drawer-overlay"
40-
/>
41-
<Sidebar />
42-
</div>
43-
</div>
46+
</DynamicMdProvider>
4447
</body>
4548
</html>
4649
);

app/sidebar.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,31 @@ import { splitMarkdown } from "./[docs_id]/splitMarkdown";
66
import { pagesList } from "./pagesList";
77
import { AccountMenu } from "./accountMenu";
88
import { ThemeToggle } from "./[docs_id]/themeToggle";
9-
import { useDynamicMdContextOptional } from "./[docs_id]/dynamicMdContext";
9+
import { useDynamicMdContext } from "./[docs_id]/dynamicMdContext";
1010

1111
const fetcher: Fetcher<string, string> = (url) =>
1212
fetch(url).then((r) => r.text());
1313

1414
export function Sidebar() {
1515
const pathname = usePathname();
1616
const docs_id = pathname.replace(/^\//, "");
17-
const dynamicMdContextValue = useDynamicMdContextOptional();
17+
const { dynamicMdContent } = useDynamicMdContext();
1818

19-
// コンテキストが利用可能な場合はそれを使用し、そうでない場合はフェッチする
19+
// コンテキストが空の場合(まだページがロードされていない場合)はフェッチする
2020
const { data, error, isLoading } = useSWR(
21-
dynamicMdContextValue ? null : `/docs/${docs_id}.md`,
21+
dynamicMdContent.length === 0 ? `/docs/${docs_id}.md` : null,
2222
fetcher
2323
);
2424

2525
if (error) console.error("Sidebar fetch error:", error);
2626

2727
// コンテキストがある場合はそれを使用、ない場合はフェッチしたデータを使用
28-
const splitmdcontent = dynamicMdContextValue?.dynamicMdContent ?? splitMarkdown(data ?? "");
28+
const splitmdcontent = dynamicMdContent.length > 0 ? dynamicMdContent : splitMarkdown(data ?? "");
2929

3030
// 現在表示中のセクション(最初にinViewがtrueのもの)を見つける
31-
const currentSectionIndex = dynamicMdContextValue?.dynamicMdContent.findIndex(
31+
const currentSectionIndex = dynamicMdContent.findIndex(
3232
(section) => section.inView
33-
) ?? -1;
33+
);
3434
return (
3535
<div className="bg-base-200 h-full w-80 overflow-y-auto">
3636
{/* todo: 背景色ほんとにこれでいい? */}

0 commit comments

Comments
 (0)