Skip to content

Commit

Permalink
Merge pull request #44 from Regulus0811/feat/class-prompt-page
Browse files Browse the repository at this point in the history
PDFビュアー機能の実装
  • Loading branch information
Lainari authored Feb 21, 2024
2 parents 3dc914c + 042c6df commit 820220a
Show file tree
Hide file tree
Showing 6 changed files with 435 additions and 9 deletions.
7 changes: 7 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
webpack: config => {
config.resolve.alias.canvas = false;

return config;
},
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"next": "14.0.4",
"react": "^18",
"react-dom": "^18",
"react-pdf": "^7.7.0",
"ts-node": "^10.9.2"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function RootLayout({children}: {children: React.ReactNode}) {
<div className="w-72 fixed">
<Navbar />
</div>
<div className="w-5/6 pl-72">{children}</div>
<div className="w-full pl-72">{children}</div>
</div>
</body>
</html>
Expand Down
11 changes: 11 additions & 0 deletions src/app/prompts/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React, {FC, ReactNode} from 'react';

interface LayoutProps {
children: ReactNode;
}

const Layout: FC<LayoutProps> = ({children}: LayoutProps) => (
<div className="flex flex-col items-center space-y-4">{children}</div>
);

export default Layout;
117 changes: 117 additions & 0 deletions src/app/prompts/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
'use client';

import React, {useState, useRef, useEffect} from 'react';
import {Document, Page, pdfjs} from 'react-pdf';
import 'react-pdf/dist/Page/TextLayer.css';
import 'react-pdf/dist/Page/AnnotationLayer.css';

pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

const MyPdfViewer = () => {
const [file, setFile] = useState<File | null>(null);
const [numPages, setNumPages] = useState<number | null>(null);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [pageNumber, setPageNumber] = useState<number>(1);
const [inputValue, setInputValue] = useState<string>('1');
const pageRefs = useRef<(React.RefObject<HTMLDivElement> | null)[]>([]);

// PDFファイルが読み込まれたときの処理
function onDocumentLoadSuccess({numPages}: {numPages: number}) {
setNumPages(numPages);
pageRefs.current = Array(numPages)
.fill(null)
.map(() => React.createRef());
}

// ファイルを選択したときの処理
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (file) {
const reader = new FileReader();
reader.onload = () => {
setFile(file);
};
reader.readAsDataURL(file);
}
};

// ページが表示されたときの処理
const observePage = (pageIndex: number) => {
const observer = new IntersectionObserver(
entries => {
if (entries[0].isIntersecting) {
setPageNumber(pageIndex + 1);
setInputValue((pageIndex + 1).toString());
}
},
{threshold: 0.5}
);

// ページが表示されたときにページ番号を更新する
const pageElement = pageRefs.current[pageIndex]?.current;
if (pageElement) {
observer.observe(pageElement);
}
return () => {
if (pageElement) {
observer.unobserve(pageElement);
}
};
};

// ページ番号を指定してページに移動する
const goToPage = (page: number) => {
const pageElement = pageRefs.current[page - 1]?.current;
if (pageElement) {
pageElement.scrollIntoView();
}
};

// ページ数が変わったときにページの表示を監視する
useEffect(() => {
const cleanupFunctions = Array(numPages || 0)
.fill(null)
.map((_, index) => observePage(index));
return () => {
cleanupFunctions.forEach(cleanup => cleanup());
};
}, [numPages]);

return (
<div>
<input type="file" onChange={handleChange} />
{file && (
<div>
<div>
<label>Page: </label>
<input
type="text"
value={inputValue}
onChange={e => setInputValue(e.target.value)}
onKeyDown={e => {
if (e.key === 'Enter') {
goToPage(Number(inputValue));
}
}}
className="border rounded p-1 w-10 text-center"
/>
/ {numPages}
</div>
<div className="h-[80vh] overflow-auto">
<Document file={file as File} onLoadSuccess={onDocumentLoadSuccess}>
{Array.from(new Array(numPages || 0), (el, index) => (
<Page
key={`page_${index + 1}`}
pageNumber={index + 1}
inputRef={pageRefs.current[index]}
/>
))}
</Document>
</div>
</div>
)}
</div>
);
};

export default MyPdfViewer;
Loading

0 comments on commit 820220a

Please sign in to comment.