diff --git a/src/components/newPdfViewer.tsx b/src/components/newPdfViewer.tsx index 32577da..68ead11 100644 --- a/src/components/newPdfViewer.tsx +++ b/src/components/newPdfViewer.tsx @@ -467,6 +467,20 @@ export default function PDFViewer({ const [isReadingMode, setIsReadingMode] = useState(false); const [showReadingCoachmark, setShowReadingCoachmark] = useState(false); const viewerRef = useRef(null); + const [urlStatus, setUrlStatus] = useState<"checking" | "ok" | "error">("checking"); + + useEffect(() => { + let isMounted = true; + fetch(url, { method: "HEAD" }) + .then(res => { + if (isMounted) setUrlStatus(res.ok ? "ok" : "error"); + }) + .catch(() => { + if (isMounted) setUrlStatus("error"); + }); + return () => { isMounted = false; }; + }, [url]); + const effectiveBackgroundColor = backgroundColor ?? (resolvedTheme === "light" ? "#F3F5FF" : "#070114"); const loaderTextColor = @@ -571,7 +585,19 @@ export default function PDFViewer({ }), ], [url, name]); -if (isLoading || !engine) { + if (urlStatus === "error") { + return ( +
+ + Paper Not Found + + This paper has been deleted or is missing from the server. + +
+ ); + } + + if (isLoading || !engine || urlStatus === "checking") { return ( } - {({ isLoaded }) => ( + {({ isLoaded, isError }) => ( <>
- + {isError ? ( +
+ + Paper Not Found + + This paper has been deleted or is missing from the server. + +
+ ) : ( + + )}
= ({ const a = document.createElement("a"); a.href = url; - a.download = getDownloadName(searchParams, "subject"); + a.download = `${getDownloadName(searchParams, "subject")}.zip`; document.body.appendChild(a); a.click(); @@ -292,7 +292,7 @@ export const FilterProvider: React.FC = ({ () => Math.ceil( (appliedFilters ? filteredPapers.length : papers.length) / - papersPerPage, + papersPerPage, ), [appliedFilters, filteredPapers.length, papers.length, papersPerPage], ); diff --git a/src/lib/posthog-server.ts b/src/lib/posthog-server.ts index fe4f3e2..d7e0bf0 100644 --- a/src/lib/posthog-server.ts +++ b/src/lib/posthog-server.ts @@ -1,8 +1,17 @@ -import { PostHog } from "posthog-node"; +/* eslint-disable @typescript-eslint/no-require-imports */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/no-unsafe-call */ +/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ + +import type { PostHog } from "posthog-node"; let posthogClient: PostHog | null = null; export function getPostHogClient(): PostHog | null { + if (posthogClient) return posthogClient; + const token = process.env.NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN; if (!token) { if (process.env.NODE_ENV !== "production") { @@ -12,7 +21,11 @@ export function getPostHogClient(): PostHog | null { } return null; } - posthogClient ??= new PostHog(token, { + + const phModule = require("posthog-node"); + const PHClass = phModule.PostHog || phModule.default?.PostHog || phModule.default || phModule; + + posthogClient ??= new PHClass(token, { host: process.env.NEXT_PUBLIC_POSTHOG_HOST, flushAt: 1, flushInterval: 0, diff --git a/src/lib/utils/download.ts b/src/lib/utils/download.ts index e72072a..5d02d10 100644 --- a/src/lib/utils/download.ts +++ b/src/lib/utils/download.ts @@ -1,6 +1,7 @@ import { type IPaper } from "../../interface"; import { extractBracketContent } from "./string"; import axios from "axios"; +import toast from "react-hot-toast"; export const getSecureUrl = (url: string): string => url.startsWith("http://") ? url.replace("http://", "https://") : url; @@ -23,6 +24,11 @@ export const downloadFile = async ( link.click(); window.URL.revokeObjectURL(link.href); } catch (error) { - console.error("Download failed:", error); + console.error("Download failed (File missing or network error):", error); + if (typeof navigator !== "undefined" && !navigator.onLine) { + toast.error("You are offline. Please check your internet connection."); + } else { + toast.error("This paper is no longer available on the server."); + } } }; \ No newline at end of file