aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohamed Bassem <me@mbassem.com>2026-02-01 16:20:28 +0000
committerMohamed Bassem <me@mbassem.com>2026-02-01 16:20:28 +0000
commit67501ed6229a63efc29b34513fac35239bd4f8e4 (patch)
treeafc668a5b01c007b3837bc9a125469929b02e608
parentfdc53eee79fdb5033b9ab46e6969917f6cd59bb0 (diff)
downloadkarakeep-67501ed6229a63efc29b34513fac35239bd4f8e4.tar.zst
fix: better looking error message when article content is unavailable
-rw-r--r--apps/web/components/dashboard/preview/ReaderView.tsx21
-rw-r--r--apps/web/lib/i18n/locales/en/translation.json2
2 files changed, 22 insertions, 1 deletions
diff --git a/apps/web/components/dashboard/preview/ReaderView.tsx b/apps/web/components/dashboard/preview/ReaderView.tsx
index d096c6a3..76070534 100644
--- a/apps/web/components/dashboard/preview/ReaderView.tsx
+++ b/apps/web/components/dashboard/preview/ReaderView.tsx
@@ -1,6 +1,8 @@
import { FullPageSpinner } from "@/components/ui/full-page-spinner";
import { toast } from "@/components/ui/sonner";
+import { useTranslation } from "@/lib/i18n/client";
import { useQuery } from "@tanstack/react-query";
+import { FileX } from "lucide-react";
import {
useCreateHighlight,
@@ -23,6 +25,7 @@ export default function ReaderView({
style?: React.CSSProperties;
readOnly: boolean;
}) {
+ const { t } = useTranslation();
const api = useTRPC();
const { data: highlights } = useQuery(
api.highlights.getForBookmark.queryOptions({
@@ -91,7 +94,23 @@ export default function ReaderView({
content = <FullPageSpinner />;
} else if (!cachedContent) {
content = (
- <div className="text-destructive">Failed to fetch link content ...</div>
+ <div className="flex h-full w-full items-center justify-center p-4">
+ <div className="max-w-sm space-y-4 text-center">
+ <div className="flex justify-center">
+ <div className="flex h-16 w-16 items-center justify-center rounded-full bg-muted">
+ <FileX className="h-8 w-8 text-muted-foreground" />
+ </div>
+ </div>
+ <div className="space-y-2">
+ <h3 className="text-lg font-medium text-foreground">
+ {t("preview.fetch_error_title")}
+ </h3>
+ <p className="text-sm leading-relaxed text-muted-foreground">
+ {t("preview.fetch_error_description")}
+ </p>
+ </div>
+ </div>
+ </div>
);
} else {
content = (
diff --git a/apps/web/lib/i18n/locales/en/translation.json b/apps/web/lib/i18n/locales/en/translation.json
index c253c313..ce607920 100644
--- a/apps/web/lib/i18n/locales/en/translation.json
+++ b/apps/web/lib/i18n/locales/en/translation.json
@@ -791,6 +791,8 @@
"cached_content": "Cached Content",
"reader_view": "Reader View",
"archive_info": "Archives may not render correctly inline if they require Javascript. For best results, <1>download it and open in your browser</1>.",
+ "fetch_error_title": "Content Unavailable",
+ "fetch_error_description": "We couldn't fetch the content for this link. The page may be protected, require authentication, or be temporarily unavailable.",
"tabs": {
"content": "Content",
"details": "Details"