This commit is contained in:
2025-06-25 14:12:31 +00:00
parent d138738e24
commit 275c572d90
8 changed files with 195 additions and 1067 deletions

View File

@@ -14,6 +14,10 @@ import {
WidthIcon,
EllipsisIcon,
CloseIcon,
JustifyTextIcon,
TextIncreaseIcon,
TextDecreaseIcon,
VRuleIcon,
} from "./icons/Icons";
createRoot(document.getElementById("root")).render(
@@ -72,7 +76,9 @@ export function TopicListView() {
return (
<>
<div className="flex-1 overflow-y-scroll pb-[156px]">
<div
className={`flex-1 overflow-y-scroll ${selectedTopic === null ? "pb-[92px]" : "pb-[156px]"}`}
>
{topics.map((topic, i) => (
<Link
key={topic.id}
@@ -96,7 +102,7 @@ export function TopicListView() {
</Link>
))}
</div>
<div className="absolute bottom-0 p-4 pb-6 w-full flex flex-col">
<div className="absolute bottom-0 p-4 w-full flex flex-col">
<div className="ml-auto p-2 flex space-x-1 h-[60px]">
<button
className={`cursor-pointer p-2 rounded-full text-white border ${config.displayTitle ? "bg-blue-100 border-blue-400" : "bg-gray-100 border-gray-400"}`}
@@ -164,7 +170,7 @@ export function TopicListView() {
{selectedTopic !== null && (
<Link
to={`/${selectedTopic.id}`}
className="w-full p-2 bg-blue-600 hover:bg-blue-700 cursor-pointer truncate rounded-md text-sm text-white text-center shadow-md transition-colors"
className="w-full p-2 mb-2 bg-blue-600 hover:bg-blue-700 cursor-pointer truncate rounded-md text-sm text-white text-center shadow-md transition-colors"
>
<span>Продължи четенето:</span>
<br />
@@ -208,24 +214,59 @@ export function Reader({ topic }) {
return (
<>
<div className="flex-1">
<PDFViewer file={topic.files[selectedVersion]} compact={config.narrowMode} />
<PDFViewer
file={topic.files[selectedVersion]}
compact={config.narrowMode}
justifyText={config.justifyText}
/>
<div className="absolute bottom-10 flex justify-between px-4 py-2 w-full z-999">
<div className="flex w-full space-x-2">
<Link to="/" className="cursor-pointer p-2 rounded-full bg-blue-600 text-white mr-auto">
<MenuBookIcon className="fill-gray-100" />
</Link>
</div>
<div className="flex space-x-1">
<div className="flex items-center">
<div className="text-sm text-gray-600 rounded bg-gray-300/30 backdrop-blur px-2">
{config.contentZoomLevel}%
</div>
<button
className={`cursor-pointer p-2 rounded-full text-white border ${config.displayTitle ? "bg-blue-100 border-blue-400" : "bg-gray-100 border-gray-400"}`}
className={`cursor-pointer p-2 mx-1 rounded-full text-white bg-gray-100/30 backdrop-blur`}
onClick={() =>
changeConfig({ contentZoomLevel: Math.max(50, config.contentZoomLevel - 10) })
}
>
<TextDecreaseIcon className="fill-gray-600" />
</button>
<button
className={`cursor-pointer p-2 rounded-full text-white bg-gray-100/30 backdrop-blur`}
onClick={() => {
changeConfig({ contentZoomLevel: Math.min(150, config.contentZoomLevel + 10) });
}}
>
<TextIncreaseIcon className="fill-gray-600" />
</button>
<VRuleIcon className="fill-gray-300" />
<button
className={`cursor-pointer p-2 mr-1 rounded-full text-white border ${config.displayTitle ? "bg-blue-100 border-blue-400" : "bg-gray-100 border-gray-400"}`}
onClick={() => changeConfig({ displayTitle: !config.displayTitle })}
>
<TitleIcon className="fill-gray-600" />
</button>
<button
className={`cursor-pointer p-2 mr-1 rounded-full text-white border ${config.justifyText ? "bg-blue-100 border-blue-400" : "bg-gray-100 border-gray-400"}`}
onClick={() => changeConfig({ justifyText: !config.justifyText })}
>
<JustifyTextIcon className="fill-gray-600" />
</button>
{window.innerWidth > 576 && (
<button
className={`cursor-pointer p-2 rounded-full text-white border ${config.narrowMode ? "bg-blue-100 border-blue-400" : "bg-gray-100 border-gray-400"}`}
className={`cursor-pointer p-2 mr-1 rounded-full text-white border ${config.narrowMode ? "bg-blue-100 border-blue-400" : "bg-gray-100 border-gray-400"}`}
onClick={() => changeConfig({ narrowMode: !config.narrowMode })}
>
<WidthIcon className="fill-gray-600" />
@@ -308,7 +349,8 @@ export function Reader({ topic }) {
);
}
export function PDFViewer({ file, compact }) {
export function PDFViewer({ file, compact, justifyText }) {
const iframeRef = useRef(null);
const [content, setContent] = useState(null);
const htmlContent = useMemo(() => {
const fileContent = `
@@ -330,12 +372,18 @@ export function PDFViewer({ file, compact }) {
padding: 0 12px 40px;
${compact ? "max-width: 36rem; margin: 0 auto;" : ""}
}
p {
text-align: justify;
text-justify: inter-word;
}
pre, code {
font-family: 'SF Mono', Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
${
justifyText
? `
p {
text-align: justify;
text-justify: inter-word;
}
pre, code {
font-family: 'SF Mono', Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
}
`
: ""
}
</style>
</head>
@@ -345,10 +393,18 @@ export function PDFViewer({ file, compact }) {
</html>
`;
return fileContent;
}, [content, compact]);
}, [content, compact, justifyText]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
const contentZoomLevel = useStore((state) => state.config.contentZoomLevel);
useEffect(() => {
if (iframeRef.current && iframeRef.current.contentDocument) {
iframeRef.current.contentDocument.body.style.zoom = `${contentZoomLevel}%`;
}
}, [contentZoomLevel]);
useEffect(() => {
const fetchFile = async () => {
try {
@@ -387,11 +443,17 @@ export function PDFViewer({ file, compact }) {
return (
<div className={`w-full h-full overflow-hidden`}>
<iframe
ref={iframeRef}
srcDoc={htmlContent}
title={`File: ${file}`}
className="w-full h-full border-0"
key={file}
allow="fullscreen"
onLoad={() => {
if (iframeRef.current?.contentDocument?.body) {
iframeRef.current.contentDocument.body.style.zoom = `${contentZoomLevel}%`;
}
}}
/>
</div>
);