implement bookmark link copy

This commit is contained in:
2025-05-21 13:47:33 +01:00
parent cfcd510193
commit 2d03f1f31b
3 changed files with 51 additions and 16 deletions

View File

@@ -26,6 +26,7 @@ function ActionBar({
function BookmarkListActionBar({ className }: { className?: string }) {
const setActiveDialog = useBookmarkPageStore((state) => state.setActiveDialog)
const statusMessage = useBookmarkPageStore((state) => state.statusMessage)
useMnemonics(
{
@@ -40,13 +41,19 @@ function BookmarkListActionBar({ className }: { className?: string }) {
return (
<ActionBar className={className}>
<Button onClick={addBookmark}>
<span className="underline">A</span>DD
</Button>
<Button>
<span className="underline">S</span>EARCH
</Button>
<LogOutButton />
{statusMessage ? (
<p>{statusMessage}</p>
) : (
<>
<Button onClick={addBookmark}>
<span className="underline">A</span>DD
</Button>
<Button>
<span className="underline">S</span>EARCH
</Button>
<LogOutButton />
</>
)}
</ActionBar>
)
}

View File

@@ -15,6 +15,7 @@ enum BookmarkListItemAction {
Open = "Open",
Edit = "Edit",
Delete = "Delete",
CopyLink = "CopyLink",
}
type SelectionChangeCallback = (bookmark: Bookmark) => void
@@ -178,12 +179,24 @@ const _BookmarkList = memo(({ className }: { className?: string }) => {
d: deleteItem,
Enter: openItem,
c: (event) => {
if (event.ctrlKey || event.metaKey) {
event.preventDefault()
copyBookmarkLink()
}
},
},
{
ignore: useCallback(() => useBookmarkPageStore.getState().activeDialog !== ActiveDialog.None, []),
},
)
async function copyBookmarkLink() {
const { bookmarks, selectedIndex, onItemAction } = store.getState()
onItemAction(bookmarks[selectedIndex], BookmarkListItemAction.CopyLink)
}
function openItem() {
const { bookmarks, selectedIndex, onItemAction } = store.getState()
expandItem()
@@ -261,6 +274,10 @@ const BookmarkListItem = memo(
onItemAction(bookmark, BookmarkListItemAction.Delete)
}
function copyItemLink() {
onItemAction(bookmark, BookmarkListItemAction.CopyLink)
}
return (
<li
className={clsx("group flex flex-row justify-start py-2", {
@@ -296,7 +313,7 @@ const BookmarkListItem = memo(
<BookmarkTagList bookmark={bookmark} />
<div className="flex flex-col space-y-1 md:flex-row md:space-y-0 md:space-x-2 items-end justify-between pt-2">
<div className="flex space-x-2">
<Button variant="light" className="text-sm">
<Button variant="light" className="text-sm" onClick={copyItemLink}>
<span>COPY LINK</span>
</Button>
<Button variant="light" className="text-sm">

View File

@@ -14,29 +14,27 @@ enum ActiveDialog {
DeleteBookmark = "DeleteBookmark",
}
const STATUS_MESSAGE_DURATION_MS = 2000
interface BookmarkPageState {
bookmarkToBeDeleted: Bookmark | null
layoutMode: LayoutMode
activeDialog: ActiveDialog
statusMessage: string
handleBookmarkListItemAction: (bookmark: Bookmark, action: BookmarkListItemAction) => void
setActiveDialog: (dialog: ActiveDialog) => void
setLayoutMode: (mode: LayoutMode) => void
showStatus: (message: string) => void
}
const useBookmarkPageStore = create<BookmarkPageState>()((set, get) => ({
bookmarkCount: 0,
bookmarks: [],
selectedBookmarkId: "",
selectedBookmarkIndex: 0,
isBookmarkItemExpanded: false,
isBookmarkPreviewOpened: false,
bookmarkToBeDeleted: null,
layoutMode: LayoutMode.Popup,
activeDialog: ActiveDialog.None,
actionBarHeight: 0,
statusMessage: "",
handleBookmarkListItemAction(bookmark: Bookmark, action: BookmarkListItemAction) {
async handleBookmarkListItemAction(bookmark: Bookmark, action: BookmarkListItemAction) {
switch (action) {
case BookmarkListItemAction.Open:
router.navigate({ to: `/bookmarks/${bookmark.id}` })
@@ -45,6 +43,12 @@ const useBookmarkPageStore = create<BookmarkPageState>()((set, get) => ({
case BookmarkListItemAction.Delete:
set({ bookmarkToBeDeleted: bookmark, activeDialog: ActiveDialog.DeleteBookmark })
break
case BookmarkListItemAction.CopyLink:
await navigator.clipboard.writeText(bookmark.url)
get().showStatus("Link copied to clipboard!")
break
default:
break
}
@@ -57,6 +61,13 @@ const useBookmarkPageStore = create<BookmarkPageState>()((set, get) => ({
setLayoutMode(mode: LayoutMode) {
set({ layoutMode: mode })
},
showStatus(message: string) {
set({ statusMessage: message })
setTimeout(() => {
set({ statusMessage: "" })
}, STATUS_MESSAGE_DURATION_MS)
},
}))
export { LayoutMode, ActiveDialog, useBookmarkPageStore }