Skip to content

Commit

Permalink
change useclipboard hook and notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
br4adam committed Jan 22, 2024
1 parent 9cfc51a commit 0fbff32
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 29 deletions.
5 changes: 3 additions & 2 deletions src/components/AddBookmarkForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ const AddBookmarkForm = () => {

const handleCreate = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault()
const toastId = toast.loading("Loading...")
if (!userId) return
const response = await createBookmark(url, userId)
if (!response.success) return toast.error(response.data)
toast.success("Bookmark added successfully!")
if (!response.success) return toast.error(response.data, { id: toastId })
toast.success("Bookmark added successfully!", { id: toastId })
getBookmarks(userId)
setUrl("")
setSelectedTag("")
Expand Down
19 changes: 11 additions & 8 deletions src/components/BookmarkDropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Fragment, useState, ReactNode } from "react"
import { Menu, Transition } from "@headlessui/react"
import { OpenInBrowser, BinMinusIn, Copy, Pin, MediaImage, RefreshDouble } from "iconoir-react"
import { OpenInBrowser, BinMinusIn, Copy, Pin, MediaImage, RefreshDouble, Check } from "iconoir-react"
import { toast } from "sonner"
import { useBookmarkStore } from "../stores/BookmarkStore"
import { useAuthStore } from "../stores/AuthStore"
Expand All @@ -15,33 +15,36 @@ type Props = {

const BookmarkDropdown = ({ bookmark }: Props) => {
const { fetch: getBookmarks, update: updateBookmark } = useBookmarkStore(state => ({ fetch: state.fetch, update: state.update }))
const { copy } = useClipboard()
const { copyToClipboard, error, copied } = useClipboard()
const session = useAuthStore(state => state.session)
const userId = session?.user.id
const [ isDeleteModalOpen, setIsDeleteModalOpen ] = useState<boolean>(false)
const [ isThumbnailModalOpen, setIsThumbnailModalOpen ] = useState<boolean>(false)

const defaultToastStyle = {style: { backgroundColor: "#18181b", borderColor: "#3f3f46" }}

const openInNewTab = (url: string) => window.open(url, "_blank")

const pinBookmark = async () => {
if (!userId) return
const response = await updateBookmark(bookmark.id, { ...bookmark, pinned: !bookmark.pinned })
if (!response.success) return toast.error(response.data)
if (response.data[0].pinned) toast("Bookmark pinned to the top!", {style: { backgroundColor: "#18181b", borderColor: "#3f3f46" }})
else toast("Bookmark unpinned!", {style: { backgroundColor: "#18181b", borderColor: "#3f3f46" }})
if (response.data[0].pinned) toast("Bookmark pinned to the top!", defaultToastStyle)
else toast("Bookmark unpinned!", defaultToastStyle)
getBookmarks(userId)
}

const copyUrl = (url: string) => {
copy(url)
toast("URL copied to clipboard!", {style: { backgroundColor: "#18181b", borderColor: "#3f3f46" }})
copyToClipboard(url)
if (error) return toast.error(error.message)
toast("URL copied to clipboard!", defaultToastStyle)
}

const refreshMetadata = async (url: string) => {
const newMetadata = await getMetadata(url)
if (!newMetadata || !userId) return toast.error("Failed to retrieve new metadata.")
const { title, domain, description, images } = newMetadata
if (bookmark.title === title && bookmark.description === description && bookmark.image === images[0]) return toast("No new data found.", {style: { backgroundColor: "#18181b", borderColor: "#3f3f46" }})
if (bookmark.title === title && bookmark.description === description && bookmark.image === images[0]) return toast("No new data found.", defaultToastStyle)
const response = await updateBookmark(bookmark.id, { ...bookmark, title: title || domain, description, image: newMetadata.images[0] })
if (!response.success) return toast.error(response.data)
toast.success("Bookmark refreshed successfully!")
Expand All @@ -63,7 +66,7 @@ const BookmarkDropdown = ({ bookmark }: Props) => {
<OpenInBrowser width={16} />Open in new tab
</MenuItem>
<MenuItem onClick={() => copyUrl(bookmark.url)}>
<Copy width={16} />Copy URL
{ copied ? <Check width={16} /> : <Copy width={16} /> } Copy URL
</MenuItem>
<MenuItem onClick={pinBookmark}>
<Pin width={16} />{ bookmark.pinned ? "Unpin" : "Pin to top" }
Expand Down
34 changes: 16 additions & 18 deletions src/hooks/useClipboard.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
import { useEffect, useState } from "react"
import { useCallback, useState } from "react"

const useClipboard = (): { copiedText: string, copy: (text: string) => void, copied: boolean } => {
const [ copied, setCopied ] = useState<boolean>(false)
const [ copiedText, setCopiedText ] = useState<string>("")
const useClipboard = (duration = 2000) => {
const [ copied, setCopied ] = useState(false)
const [ error, setError ] = useState<Error | null>(null)

const copy = (text: string): void => {
if (!navigator.clipboard) return
navigator.clipboard.writeText(text)
setCopied(true)
setCopiedText(text)
}
const copyToClipboard = useCallback(
async (text: string) => {
try {
await navigator.clipboard.writeText(text)
setCopied(true)
setError(null)
setTimeout(() => setCopied(false), duration)
} catch (error) {
setError(error instanceof Error ? error : new Error("Failed to copy url!"))
}
}, [duration])

useEffect(() => {
if (copied) {
const timeoutId = setTimeout(() => setCopied(false), 2000)
return () => clearTimeout(timeoutId)
}
}, [copied])

return { copiedText, copy, copied }
return { copied, error, copyToClipboard }
}

export default useClipboard
2 changes: 1 addition & 1 deletion src/stores/BookmarkStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const useBookmarkStore = create<BookmarkState>(set => ({
try {
set({ loading: true })
const metadata = await getMetadata(url)
if (!metadata) return { data: "Please insert a valid URL!", success: false }
if (!metadata) return { data: "Please provide a valid URL starting with https!", success: false }
const { data, error } = await supabase
.from("bookmarks")
.insert({ title: metadata.title || metadata.domain, domain: metadata.domain, url: metadata.url, description: metadata.description, image: metadata.images[0], saved_by: userId, tags: [] })
Expand Down

0 comments on commit 0fbff32

Please sign in to comment.