aboutsummaryrefslogtreecommitdiffstats
path: root/apps/web/components
diff options
context:
space:
mode:
authorOlicorne <26625900+thiswillbeyourgithub@users.noreply.github.com>2025-05-18 20:45:32 +0200
committerGitHub <noreply@github.com>2025-05-18 19:45:32 +0100
commit053d1a905ed6cef71151d168351f22b35ddca986 (patch)
tree2c588c748e288a602b2c3c1a579724d63382a16d /apps/web/components
parent0e734b6b1c1fc332b34309d1c060beb8569c6fba (diff)
downloadkarakeep-053d1a905ed6cef71151d168351f22b35ddca986.tar.zst
fix(web): Switch to a tab view in small screens for bookmark previews
* feat: Implement tabbed layout for bookmark preview content and details * feat: Enable swipe gesture to switch between content and details tabs * feat: add scroll-based tab bar hide/show functionality * fix: adjust tab bar layout to maintain content space when hidden * fix: bg-muted was stopping midway in the background * fix: disable mouse tracking for swipe detection in BookmarkPreview * fix: improve scroll behavior to prevent glitchy tab bar animation * Update apps/web/components/dashboard/preview/BookmarkPreview.tsx Co-authored-by: xuatz <xzlow10@gmail.com> * Update apps/web/components/dashboard/preview/BookmarkPreview.tsx Co-authored-by: xuatz <xzlow10@gmail.com> * feat: add responsive layout with tabs and swipe for BookmarkPreview * Remove react swipe, scroll handlers and do screen detection using media queries * Revert the grey background for the main content * remove react-swip from the package.json * more fixes * Fix the black area under the tab bar --------- Co-authored-by: xuatz <xzlow10@gmail.com> Co-authored-by: Mohamed Bassem <me@mbassem.com>
Diffstat (limited to 'apps/web/components')
-rw-r--r--apps/web/components/dashboard/preview/BookmarkPreview.tsx116
1 files changed, 80 insertions, 36 deletions
diff --git a/apps/web/components/dashboard/preview/BookmarkPreview.tsx b/apps/web/components/dashboard/preview/BookmarkPreview.tsx
index df09f687..c09bc949 100644
--- a/apps/web/components/dashboard/preview/BookmarkPreview.tsx
+++ b/apps/web/components/dashboard/preview/BookmarkPreview.tsx
@@ -1,11 +1,12 @@
"use client";
-import React from "react";
+import { useState } from "react";
import Link from "next/link";
import { BookmarkTagsEditor } from "@/components/dashboard/bookmarks/BookmarkTagsEditor";
import { FullPageSpinner } from "@/components/ui/full-page-spinner";
import { Separator } from "@/components/ui/separator";
import { Skeleton } from "@/components/ui/skeleton";
+import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import {
Tooltip,
TooltipContent,
@@ -68,6 +69,8 @@ export default function BookmarkPreview({
initialData?: ZBookmark;
}) {
const { t } = useTranslation();
+ const [activeTab, setActiveTab] = useState<string>("content");
+
const { data: bookmark } = api.bookmarks.getBookmark.useQuery(
{
bookmarkId,
@@ -111,45 +114,86 @@ export default function BookmarkPreview({
const sourceUrl = getSourceUrl(bookmark);
const title = getBookmarkTitle(bookmark);
- return (
- <div className="grid h-full grid-rows-3 gap-2 overflow-hidden bg-background lg:grid-cols-3 lg:grid-rows-none">
- <div className="row-span-2 h-full w-full overflow-auto p-2 md:col-span-2 lg:row-auto">
- {isBookmarkStillCrawling(bookmark) ? <ContentLoading /> : content}
- </div>
- <div className="row-span-1 flex flex-col gap-4 overflow-auto bg-accent p-4 md:col-span-2 lg:col-span-1 lg:row-auto">
- <div className="flex w-full flex-col items-center justify-center gap-y-2">
- <div className="flex w-full items-center justify-center gap-2">
- <p className="line-clamp-2 text-ellipsis break-words text-lg">
- {title === undefined || title === "" ? "Untitled" : title}
- </p>
- </div>
- {sourceUrl && (
- <Link
- href={sourceUrl}
- target="_blank"
- className="flex items-center gap-2 text-gray-400"
- >
- <span>{t("preview.view_original")}</span>
- <ExternalLink />
- </Link>
- )}
- <Separator />
+ // Common content for both layouts
+ const contentSection = isBookmarkStillCrawling(bookmark) ? (
+ <ContentLoading />
+ ) : (
+ content
+ );
+
+ const detailsSection = (
+ <div className="flex flex-col gap-4">
+ <div className="flex w-full flex-col items-center justify-center gap-y-2">
+ <div className="flex w-full items-center justify-center gap-2">
+ <p className="line-clamp-2 text-ellipsis break-words text-lg">
+ {title === undefined || title === "" ? "Untitled" : title}
+ </p>
</div>
+ {sourceUrl && (
+ <Link
+ href={sourceUrl}
+ target="_blank"
+ className="flex items-center gap-2 text-gray-400"
+ >
+ <span>{t("preview.view_original")}</span>
+ <ExternalLink />
+ </Link>
+ )}
+ <Separator />
+ </div>
+ <CreationTime createdAt={bookmark.createdAt} />
+ <SummarizeBookmarkArea bookmark={bookmark} />
+ <div className="flex items-center gap-4">
+ <p className="text-sm text-gray-400">{t("common.tags")}</p>
+ <BookmarkTagsEditor bookmark={bookmark} />
+ </div>
+ <div className="flex gap-4">
+ <p className="pt-2 text-sm text-gray-400">{t("common.note")}</p>
+ <NoteEditor bookmark={bookmark} />
+ </div>
+ <AttachmentBox bookmark={bookmark} />
+ <HighlightsBox bookmarkId={bookmark.id} />
+ <ActionBar bookmark={bookmark} />
+ </div>
+ );
- <CreationTime createdAt={bookmark.createdAt} />
- <SummarizeBookmarkArea bookmark={bookmark} />
- <div className="flex items-center gap-4">
- <p className="text-sm text-gray-400">{t("common.tags")}</p>
- <BookmarkTagsEditor bookmark={bookmark} />
+ return (
+ <>
+ {/* Render original layout for wide screens */}
+ <div className="hidden h-full grid-cols-3 overflow-hidden bg-background lg:grid">
+ <div className="col-span-2 h-full w-full overflow-auto p-2">
+ {contentSection}
</div>
- <div className="flex gap-4">
- <p className="pt-2 text-sm text-gray-400">{t("common.note")}</p>
- <NoteEditor bookmark={bookmark} />
+ <div className="flex flex-col gap-4 overflow-auto bg-accent p-4">
+ {detailsSection}
</div>
- <AttachmentBox bookmark={bookmark} />
- <HighlightsBox bookmarkId={bookmark.id} />
- <ActionBar bookmark={bookmark} />
</div>
- </div>
+
+ {/* Render tabbed layout for narrow/vertical screens */}
+ <Tabs
+ value={activeTab}
+ onValueChange={setActiveTab}
+ className="flex h-full w-full flex-col overflow-hidden lg:hidden"
+ >
+ <TabsList
+ className={`sticky top-0 z-10 grid h-auto w-full grid-cols-2`}
+ >
+ <TabsTrigger value="content">{t("preview.tabs.content")}</TabsTrigger>
+ <TabsTrigger value="details">{t("preview.tabs.details")}</TabsTrigger>
+ </TabsList>
+ <TabsContent
+ value="content"
+ className="h-full flex-1 overflow-hidden overflow-y-auto bg-background p-2 data-[state=inactive]:hidden"
+ >
+ {contentSection}
+ </TabsContent>
+ <TabsContent
+ value="details"
+ className="h-full overflow-y-auto bg-accent p-4 data-[state=inactive]:hidden"
+ >
+ {detailsSection}
+ </TabsContent>
+ </Tabs>
+ </>
);
}