This commit is contained in:
Tomas Mirchev 2025-06-30 19:17:30 +00:00
parent bcf8591719
commit ff959fd46e
5 changed files with 50 additions and 25 deletions

View File

@ -1,5 +1,13 @@
import { StrictMode, Fragment, useLayoutEffect, useRef, useState, useEffect, useMemo } from "react"; import { StrictMode, Fragment, useLayoutEffect, useRef, useState, useEffect, useMemo } from "react";
import { Navigate, BrowserRouter, Link, Outlet, Route, Routes } from "react-router"; import {
Navigate,
useSearchParams,
BrowserRouter,
Link,
Outlet,
Route,
Routes,
} from "react-router";
import { marked } from "marked"; import { marked } from "marked";
import { resourcesInstance } from "./api.js"; import { resourcesInstance } from "./api.js";
import { useStore } from "./store.js"; import { useStore } from "./store.js";
@ -20,6 +28,7 @@ import {
VRuleIcon, VRuleIcon,
} from "./icons/Icons"; } from "./icons/Icons";
import ResourcePage from "./ResourcePage.jsx"; import ResourcePage from "./ResourcePage.jsx";
import NamePage from "./NamePage.jsx";
import io from "socket.io-client"; import io from "socket.io-client";
//const socket = io("http://localhost:3000"); //const socket = io("http://localhost:3000");
@ -134,6 +143,7 @@ export function App() {
<Route path=":topicId" element={<FileReader />} /> <Route path=":topicId" element={<FileReader />} />
</Route> </Route>
<Route path="/edit" element={<ResourcePage />} /> <Route path="/edit" element={<ResourcePage />} />
<Route path="/name" element={<NamePage />} />
</Routes> </Routes>
</BrowserRouter> </BrowserRouter>
<ToastContainer /> <ToastContainer />
@ -161,7 +171,19 @@ function LoadingWrapper({ children }) {
function Layout() { function Layout() {
const config = useStore((state) => state.config); const config = useStore((state) => state.config);
const changeConfig = useStore((state) => state.changeConfig);
const topic = useTopic(); const topic = useTopic();
const [searchParams, setSearchParams] = useSearchParams();
useEffect(() => {
if (searchParams.has("v")) {
const resV = Number(searchParams.get("v"));
if (typeof resV === "number" && resV >= 0 && resV <= 8) {
changeConfig({ version: resV });
}
setSearchParams({});
}
}, [searchParams, changeConfig, setSearchParams]);
return ( return (
<div className="max-w-7xl mx-auto h-full relative flex flex-col"> <div className="max-w-7xl mx-auto h-full relative flex flex-col">
@ -298,7 +320,7 @@ export function Reader({ topic }) {
const resourceIdx = useStore((state) => state.resourceIdx); const resourceIdx = useStore((state) => state.resourceIdx);
const selectResource = useStore((state) => state.selectResource); const selectResource = useStore((state) => state.selectResource);
console.log(resourceIdx);
const selectedResource = topic.resources[resourceIdx]; const selectedResource = topic.resources[resourceIdx];
return ( return (

3
reader/src/NamePage.jsx Normal file
View File

@ -0,0 +1,3 @@
export default function NamePage() {
return <div>Hello name page</div>;
}

View File

@ -17,6 +17,7 @@ function LoadingWrapper() {
} }
function SelectResource({ topics, selectedTopic, selectedResource, onChange, disabled }) { function SelectResource({ topics, selectedTopic, selectedResource, onChange, disabled }) {
const version = useStore((state) => state.config.version);
function handleChange(newTopicIdx, newResourceIdx) { function handleChange(newTopicIdx, newResourceIdx) {
if (disabled) { if (disabled) {
return; return;
@ -43,7 +44,7 @@ function SelectResource({ topics, selectedTopic, selectedResource, onChange, dis
id="topicSelect" id="topicSelect"
value={selectedTopic.seq - 1} value={selectedTopic.seq - 1}
onChange={(event) => { onChange={(event) => {
handleChange(parseInt(event.target.value), 0); handleChange(parseInt(event.target.value), version);
}} }}
className="disabled:bg-gray-50 disabled:text-gray-500 px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white" className="disabled:bg-gray-50 disabled:text-gray-500 px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white"
> >
@ -121,8 +122,9 @@ const ResourcePage = ({ topics }) => {
const [tokenInput, setTokenInput] = useState(""); const [tokenInput, setTokenInput] = useState("");
// Topic + resource // Topic + resource
const version = useStore((state) => state.config.version);
const [topicIdx, setTopicIdx] = useState(0); const [topicIdx, setTopicIdx] = useState(0);
const [resourceIdx, setResourceIdx] = useState(0); const [resourceIdx, setResourceIdx] = useState(version);
const setStructure = useStore((state) => state.setStructure); const setStructure = useStore((state) => state.setStructure);
const selectedTopic = topics[topicIdx]; const selectedTopic = topics[topicIdx];
const selectedResource = selectedTopic.resources[resourceIdx]; const selectedResource = selectedTopic.resources[resourceIdx];
@ -170,19 +172,18 @@ const ResourcePage = ({ topics }) => {
}, [content]); }, [content]);
const handleLoad = () => { const handleLoad = () => {
return; //const iframe = iframeRef.current;
const iframe = iframeRef.current; //if (iframe) {
if (iframe) { // try {
try { // // Only works for same-origin content
// Only works for same-origin content // const contentHeight = iframe.contentDocument.body.scrollHeight;
const contentHeight = iframe.contentDocument.body.scrollHeight; // if (contentHeight > 100) {
if (contentHeight > 100) { // iframe.style.height = contentHeight + "px";
iframe.style.height = contentHeight + "px"; // }
} // } catch (error) {
} catch (error) { // console.log("Cross-origin iframe - cannot access content height");
console.log("Cross-origin iframe - cannot access content height"); // }
} //}
}
}; };
const handleTokenSubmit = () => { const handleTokenSubmit = () => {

View File

@ -20,7 +20,7 @@ export const useStore = create((set, get) => ({
if (topicIdx === null) { if (topicIdx === null) {
set({ topicIdx, resourceIdx: null }); set({ topicIdx, resourceIdx: null });
} else { } else {
set({ topicIdx, resourceIdx: 0 }); set({ topicIdx, resourceIdx: get().config.version });
} }
}, },
selectResource: (resourceIdx) => { selectResource: (resourceIdx) => {
@ -59,6 +59,7 @@ function getLocalConfig() {
narrowMode: true, narrowMode: true,
justifyText: false, justifyText: false,
contentZoomLevel: 100, contentZoomLevel: 100,
version: 0,
}; };
const config_str = localStorage.getItem("config"); const config_str = localStorage.getItem("config");
const config = config_str ? JSON.parse(config_str) : {}; const config = config_str ? JSON.parse(config_str) : {};

View File

@ -124,8 +124,8 @@ app.post(
verifyToken, verifyToken,
asyncHandler(async (req, res) => { asyncHandler(async (req, res) => {
try { try {
const { topicSeq, resourceSeq, content } = req.body; const { topicSeq, resourceSeq, content = "" } = req.body;
if (!topicSeq || !resourceSeq || !content) { if (!topicSeq || !resourceSeq) {
res.status(400).json({ message: "Missing body" }); res.status(400).json({ message: "Missing body" });
return; return;
} }
@ -186,11 +186,9 @@ app.post(
} }
if (sourceResourceSeq === targetResourceSeq) { if (sourceResourceSeq === targetResourceSeq) {
res res.status(400).json({
.status(400) message: "Source and target resource sequences cannot be the same",
.json({ });
message: "Source and target resource sequences cannot be the same",
});
return; return;
} }