Skip to content

Commit

Permalink
feature(web): Allow uploading directly into lists/tags. Fixes #69
Browse files Browse the repository at this point in the history
  • Loading branch information
MohamedBassem committed Apr 9, 2024
1 parent 994691b commit fe13408
Show file tree
Hide file tree
Showing 19 changed files with 258 additions and 144 deletions.
1 change: 1 addition & 0 deletions apps/web/app/dashboard/archive/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default async function ArchivedBookmarkPage() {
}
query={{ archived: true }}
showDivider={true}
showEditorCard={true}
/>
);
}
21 changes: 9 additions & 12 deletions apps/web/app/dashboard/bookmarks/page.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
import React from "react";
import Bookmarks from "@/components/dashboard/bookmarks/Bookmarks";
import TopNav from "@/components/dashboard/bookmarks/TopNav";
import UploadDropzone from "@/components/dashboard/UploadDropzone";
import { Separator } from "@/components/ui/separator";

export default async function BookmarksPage() {
return (
<div>
<UploadDropzone>
<TopNav />
<Separator />
<div className="my-4 flex-1">
<Bookmarks
header={<p className="text-2xl">Bookmarks</p>}
query={{ archived: false }}
showEditorCard={true}
/>
</div>
</UploadDropzone>
<TopNav />
<Separator />
<div className="my-4 flex-1">
<Bookmarks
header={<p className="text-2xl">Bookmarks</p>}
query={{ archived: false }}
showEditorCard={true}
/>
</div>
</div>
);
}
1 change: 1 addition & 0 deletions apps/web/app/dashboard/favourites/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export default async function FavouritesBookmarkPage() {
header={<p className="text-2xl">⭐️ Favourites</p>}
query={{ favourited: true }}
showDivider={true}
showEditorCard={true}
/>
);
}
2 changes: 1 addition & 1 deletion apps/web/app/dashboard/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default async function Dashboard({
<MobileSidebar />
<Separator />
</div>
<div className="container p-4">{children}</div>
<div className="container min-h-screen p-4">{children}</div>
</main>
</div>
);
Expand Down
28 changes: 13 additions & 15 deletions apps/web/app/dashboard/lists/[listId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { notFound } from "next/navigation";
import Bookmarks from "@/components/dashboard/bookmarks/Bookmarks";
import DeleteListButton from "@/components/dashboard/lists/DeleteListButton";
import { BookmarkListContextProvider } from "@/lib/hooks/list-context";
import { api } from "@/server/api/client";
import { TRPCError } from "@trpc/server";

Expand All @@ -23,19 +22,18 @@ export default async function ListPage({
}

return (
<BookmarkListContextProvider listId={list.id}>
<Bookmarks
query={{ listId: list.id }}
showDivider={true}
header={
<div className="flex justify-between">
<span className="text-2xl">
{list.icon} {list.name}
</span>
<DeleteListButton list={list} />
</div>
}
/>
</BookmarkListContextProvider>
<Bookmarks
query={{ listId: list.id }}
showDivider={true}
showEditorCard={true}
header={
<div className="flex justify-between">
<span className="text-2xl">
{list.icon} {list.name}
</span>
<DeleteListButton list={list} />
</div>
}
/>
);
}
1 change: 1 addition & 0 deletions apps/web/app/dashboard/tags/[tagName]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export default async function TagPage({
</div>
}
query={{ tagId: tag.id }}
showEditorCard={true}
/>
);
}
25 changes: 10 additions & 15 deletions apps/web/components/dashboard/UploadDropzone.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"use client";

import React, { useState } from "react";
import { api } from "@/lib/trpc";
import { cn } from "@/lib/utils";
import { useMutation } from "@tanstack/react-query";
import { TRPCClientError } from "@trpc/client";
import DropZone from "react-dropzone";

import { useCreateBookmarkWithPostHook } from "@hoarder/shared-react/hooks/bookmarks";
import {
zUploadErrorSchema,
zUploadResponseSchema,
Expand All @@ -16,20 +16,15 @@ import LoadingSpinner from "../ui/spinner";
import { toast } from "../ui/use-toast";

function useUploadAsset({ onComplete }: { onComplete: () => void }) {
const invalidateAllBookmarks =
api.useUtils().bookmarks.getBookmarks.invalidate;

const { mutateAsync: createBookmark } =
api.bookmarks.createBookmark.useMutation({
onSuccess: () => {
toast({ description: "Bookmark uploaded" });
invalidateAllBookmarks();
onComplete();
},
onError: () => {
toast({ description: "Something went wrong", variant: "destructive" });
},
});
const { mutateAsync: createBookmark } = useCreateBookmarkWithPostHook({
onSuccess: () => {
toast({ description: "Bookmark uploaded" });
onComplete();
},
onError: () => {
toast({ description: "Something went wrong", variant: "destructive" });
},
});

const { mutateAsync: runUpload } = useMutation({
mutationFn: async (file: File) => {
Expand Down
6 changes: 3 additions & 3 deletions apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { useContext, useState } from "react";
import { useState } from "react";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
Expand All @@ -10,7 +10,6 @@ import {
} from "@/components/ui/dropdown-menu";
import { useToast } from "@/components/ui/use-toast";
import { useClientConfig } from "@/lib/clientConfig";
import { BookmarkListContext } from "@/lib/hooks/list-context";
import {
Link,
List,
Expand All @@ -29,6 +28,7 @@ import {
useUpdateBookmark,
} from "@hoarder/shared-react/hooks//bookmarks";
import { useRemoveBookmarkFromList } from "@hoarder/shared-react/hooks//lists";
import { useBookmarkGridContext } from "@hoarder/shared-react/hooks/bookmark-grid-context";

import { useAddToListModal } from "./AddToListModal";
import { BookmarkedTextEditor } from "./BookmarkedTextEditor";
Expand All @@ -48,7 +48,7 @@ export default function BookmarkOptions({ bookmark }: { bookmark: ZBookmark }) {

const [isTextEditorOpen, setTextEditorOpen] = useState(false);

const { listId } = useContext(BookmarkListContext);
const { listId } = useBookmarkGridContext() ?? {};

const onError = () => {
toast({
Expand Down
38 changes: 7 additions & 31 deletions apps/web/components/dashboard/bookmarks/BookmarkedTextEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function BookmarkedTextEditor({
open,
setOpen,
}: {
bookmark?: ZBookmark;
bookmark: ZBookmark;
open: boolean;
setOpen: (open: boolean) => void;
}) {
Expand All @@ -30,30 +30,14 @@ export function BookmarkedTextEditor({
bookmark && bookmark.content.type == "text" ? bookmark.content.text : "",
);

const invalidateAllBookmarksCache =
api.useUtils().bookmarks.getBookmarks.invalidate;
const invalidateOneBookmarksCache =
api.useUtils().bookmarks.getBookmark.invalidate;

const { mutate: createBookmarkMutator, isPending: isCreationPending } =
api.bookmarks.createBookmark.useMutation({
onSuccess: () => {
invalidateAllBookmarksCache();
toast({
description: "Note created!",
});
setOpen(false);
setNoteText("");
},
onError: () => {
toast({ description: "Something went wrong", variant: "destructive" });
},
});
const { mutate: updateBookmarkMutator, isPending: isUpdatePending } =
const { mutate: updateBookmarkMutator, isPending } =
api.bookmarks.updateBookmarkText.useMutation({
onSuccess: () => {
invalidateOneBookmarksCache({
bookmarkId: bookmark!.id,
bookmarkId: bookmark.id,
});
toast({
description: "Note updated!",
Expand All @@ -64,20 +48,12 @@ export function BookmarkedTextEditor({
toast({ description: "Something went wrong", variant: "destructive" });
},
});
const isPending = isCreationPending || isUpdatePending;

const onSave = () => {
if (isNewBookmark) {
createBookmarkMutator({
type: "text",
text: noteText,
});
} else {
updateBookmarkMutator({
bookmarkId: bookmark.id,
text: noteText,
});
}
updateBookmarkMutator({
bookmarkId: bookmark.id,
text: noteText,
});
};

return (
Expand Down
21 changes: 10 additions & 11 deletions apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
"use client";

import { useMemo } from "react";
import { ActionButton } from "@/components/ui/action-button";
import tailwindConfig from "@/tailwind.config";
Expand Down Expand Up @@ -78,15 +76,16 @@ export default function BookmarksGrid({
{bookmarks.map((b) => renderBookmark(b))}
</Masonry>
{hasNextPage && (
<ActionButton
ignoreDemoMode={true}
loading={isFetchingNextPage}
onClick={() => fetchNextPage()}
className="mx-auto w-min"
variant="ghost"
>
Load More
</ActionButton>
<div className="flex justify-center">
<ActionButton
ignoreDemoMode={true}
loading={isFetchingNextPage}
onClick={() => fetchNextPage()}
variant="ghost"
>
Load More
</ActionButton>
</div>
)}
</>
);
Expand Down
7 changes: 3 additions & 4 deletions apps/web/components/dashboard/bookmarks/EditorCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import { Separator } from "@/components/ui/separator";
import { Textarea } from "@/components/ui/textarea";
import { toast } from "@/components/ui/use-toast";
import { useClientConfig } from "@/lib/clientConfig";
import { api } from "@/lib/trpc";
import { cn } from "@/lib/utils";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";

import { useCreateBookmarkWithPostHook } from "@hoarder/shared-react/hooks/bookmarks";

function useFocusOnKeyPress(inputRef: React.RefObject<HTMLTextAreaElement>) {
useEffect(() => {
function handleKeyPress(e: KeyboardEvent) {
Expand Down Expand Up @@ -47,10 +48,8 @@ export default function EditorCard({ className }: { className?: string }) {
useImperativeHandle(ref, () => inputRef.current);
useFocusOnKeyPress(inputRef);

const invalidateBookmarksCache = api.useUtils().bookmarks.invalidate;
const { mutate, isPending } = api.bookmarks.createBookmark.useMutation({
const { mutate, isPending } = useCreateBookmarkWithPostHook({
onSuccess: () => {
invalidateBookmarksCache();
form.reset();
},
onError: () => {
Expand Down
14 changes: 7 additions & 7 deletions apps/web/components/dashboard/bookmarks/TagsEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import CreateableSelect from "react-select/creatable";

import type { ZBookmark } from "@hoarder/trpc/types/bookmarks";
import type { ZAttachedByEnum } from "@hoarder/trpc/types/tags";
import { useUpdateBookmarkTags } from "@hoarder/shared-react/hooks/bookmarks";

interface EditableTag {
attachedBy: ZAttachedByEnum;
Expand All @@ -17,16 +18,12 @@ interface EditableTag {

export function TagsEditor({ bookmark }: { bookmark: ZBookmark }) {
const demoMode = !!useClientConfig().demoMode;
const apiUtils = api.useUtils();

const { mutate } = api.bookmarks.updateTags.useMutation({
const { mutate } = useUpdateBookmarkTags({
onSuccess: () => {
toast({
description: "Tags has been updated!",
});
apiUtils.bookmarks.getBookmark.invalidate({ bookmarkId: bookmark.id });
apiUtils.tags.list.invalidate();
apiUtils.tags.get.invalidate();
},
onError: () => {
toast({
Expand Down Expand Up @@ -58,7 +55,7 @@ export function TagsEditor({ bookmark }: { bookmark: ZBookmark }) {
case "create-option": {
mutate({
bookmarkId: bookmark.id,
attach: [{ tag: actionMeta.option.label }],
attach: [{ tagName: actionMeta.option.label }],
detach: [],
});
break;
Expand All @@ -68,7 +65,10 @@ export function TagsEditor({ bookmark }: { bookmark: ZBookmark }) {
mutate({
bookmarkId: bookmark.id,
attach: [
{ tag: actionMeta.option.label, tagId: actionMeta.option?.value },
{
tagName: actionMeta.option.label,
tagId: actionMeta.option?.value,
},
],
detach: [],
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
"use client";

import UploadDropzone from "@/components/dashboard/UploadDropzone";
import { api } from "@/lib/trpc";

import type {
ZGetBookmarksRequest,
ZGetBookmarksResponse,
} from "@hoarder/trpc/types/bookmarks";
import { BookmarkGridContextProvider } from "@hoarder/shared-react/hooks/bookmark-grid-context";

import BookmarksGrid from "./BookmarksGrid";

Expand All @@ -29,7 +31,7 @@ export default function UpdatableBookmarksGrid({
getNextPageParam: (lastPage) => lastPage.nextCursor,
});

return (
const grid = (
<BookmarksGrid
bookmarks={data!.pages.flatMap((b) => b.bookmarks)}
hasNextPage={hasNextPage}
Expand All @@ -38,4 +40,10 @@ export default function UpdatableBookmarksGrid({
showEditorCard={showEditorCard}
/>
);

return (
<BookmarkGridContextProvider query={query}>
{showEditorCard ? <UploadDropzone>{grid}</UploadDropzone> : grid}
</BookmarkGridContextProvider>
);
}
Loading

0 comments on commit fe13408

Please sign in to comment.