implement bookmark link copy
This commit is contained in:
@@ -26,6 +26,7 @@ function ActionBar({
|
|||||||
|
|
||||||
function BookmarkListActionBar({ className }: { className?: string }) {
|
function BookmarkListActionBar({ className }: { className?: string }) {
|
||||||
const setActiveDialog = useBookmarkPageStore((state) => state.setActiveDialog)
|
const setActiveDialog = useBookmarkPageStore((state) => state.setActiveDialog)
|
||||||
|
const statusMessage = useBookmarkPageStore((state) => state.statusMessage)
|
||||||
|
|
||||||
useMnemonics(
|
useMnemonics(
|
||||||
{
|
{
|
||||||
@@ -40,13 +41,19 @@ function BookmarkListActionBar({ className }: { className?: string }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ActionBar className={className}>
|
<ActionBar className={className}>
|
||||||
<Button onClick={addBookmark}>
|
{statusMessage ? (
|
||||||
<span className="underline">A</span>DD
|
<p>{statusMessage}</p>
|
||||||
</Button>
|
) : (
|
||||||
<Button>
|
<>
|
||||||
<span className="underline">S</span>EARCH
|
<Button onClick={addBookmark}>
|
||||||
</Button>
|
<span className="underline">A</span>DD
|
||||||
<LogOutButton />
|
</Button>
|
||||||
|
<Button>
|
||||||
|
<span className="underline">S</span>EARCH
|
||||||
|
</Button>
|
||||||
|
<LogOutButton />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</ActionBar>
|
</ActionBar>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,7 @@ enum BookmarkListItemAction {
|
|||||||
Open = "Open",
|
Open = "Open",
|
||||||
Edit = "Edit",
|
Edit = "Edit",
|
||||||
Delete = "Delete",
|
Delete = "Delete",
|
||||||
|
CopyLink = "CopyLink",
|
||||||
}
|
}
|
||||||
|
|
||||||
type SelectionChangeCallback = (bookmark: Bookmark) => void
|
type SelectionChangeCallback = (bookmark: Bookmark) => void
|
||||||
@@ -178,12 +179,24 @@ const _BookmarkList = memo(({ className }: { className?: string }) => {
|
|||||||
d: deleteItem,
|
d: deleteItem,
|
||||||
|
|
||||||
Enter: openItem,
|
Enter: openItem,
|
||||||
|
|
||||||
|
c: (event) => {
|
||||||
|
if (event.ctrlKey || event.metaKey) {
|
||||||
|
event.preventDefault()
|
||||||
|
copyBookmarkLink()
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ignore: useCallback(() => useBookmarkPageStore.getState().activeDialog !== ActiveDialog.None, []),
|
ignore: useCallback(() => useBookmarkPageStore.getState().activeDialog !== ActiveDialog.None, []),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async function copyBookmarkLink() {
|
||||||
|
const { bookmarks, selectedIndex, onItemAction } = store.getState()
|
||||||
|
onItemAction(bookmarks[selectedIndex], BookmarkListItemAction.CopyLink)
|
||||||
|
}
|
||||||
|
|
||||||
function openItem() {
|
function openItem() {
|
||||||
const { bookmarks, selectedIndex, onItemAction } = store.getState()
|
const { bookmarks, selectedIndex, onItemAction } = store.getState()
|
||||||
expandItem()
|
expandItem()
|
||||||
@@ -261,6 +274,10 @@ const BookmarkListItem = memo(
|
|||||||
onItemAction(bookmark, BookmarkListItemAction.Delete)
|
onItemAction(bookmark, BookmarkListItemAction.Delete)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function copyItemLink() {
|
||||||
|
onItemAction(bookmark, BookmarkListItemAction.CopyLink)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
className={clsx("group flex flex-row justify-start py-2", {
|
className={clsx("group flex flex-row justify-start py-2", {
|
||||||
@@ -296,7 +313,7 @@ const BookmarkListItem = memo(
|
|||||||
<BookmarkTagList bookmark={bookmark} />
|
<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 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">
|
<div className="flex space-x-2">
|
||||||
<Button variant="light" className="text-sm">
|
<Button variant="light" className="text-sm" onClick={copyItemLink}>
|
||||||
<span>COPY LINK</span>
|
<span>COPY LINK</span>
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="light" className="text-sm">
|
<Button variant="light" className="text-sm">
|
||||||
|
@@ -14,29 +14,27 @@ enum ActiveDialog {
|
|||||||
DeleteBookmark = "DeleteBookmark",
|
DeleteBookmark = "DeleteBookmark",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const STATUS_MESSAGE_DURATION_MS = 2000
|
||||||
|
|
||||||
interface BookmarkPageState {
|
interface BookmarkPageState {
|
||||||
bookmarkToBeDeleted: Bookmark | null
|
bookmarkToBeDeleted: Bookmark | null
|
||||||
layoutMode: LayoutMode
|
layoutMode: LayoutMode
|
||||||
activeDialog: ActiveDialog
|
activeDialog: ActiveDialog
|
||||||
|
statusMessage: string
|
||||||
|
|
||||||
handleBookmarkListItemAction: (bookmark: Bookmark, action: BookmarkListItemAction) => void
|
handleBookmarkListItemAction: (bookmark: Bookmark, action: BookmarkListItemAction) => void
|
||||||
setActiveDialog: (dialog: ActiveDialog) => void
|
setActiveDialog: (dialog: ActiveDialog) => void
|
||||||
setLayoutMode: (mode: LayoutMode) => void
|
setLayoutMode: (mode: LayoutMode) => void
|
||||||
|
showStatus: (message: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const useBookmarkPageStore = create<BookmarkPageState>()((set, get) => ({
|
const useBookmarkPageStore = create<BookmarkPageState>()((set, get) => ({
|
||||||
bookmarkCount: 0,
|
|
||||||
bookmarks: [],
|
|
||||||
selectedBookmarkId: "",
|
|
||||||
selectedBookmarkIndex: 0,
|
|
||||||
isBookmarkItemExpanded: false,
|
|
||||||
isBookmarkPreviewOpened: false,
|
|
||||||
bookmarkToBeDeleted: null,
|
bookmarkToBeDeleted: null,
|
||||||
layoutMode: LayoutMode.Popup,
|
layoutMode: LayoutMode.Popup,
|
||||||
activeDialog: ActiveDialog.None,
|
activeDialog: ActiveDialog.None,
|
||||||
actionBarHeight: 0,
|
statusMessage: "",
|
||||||
|
|
||||||
handleBookmarkListItemAction(bookmark: Bookmark, action: BookmarkListItemAction) {
|
async handleBookmarkListItemAction(bookmark: Bookmark, action: BookmarkListItemAction) {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case BookmarkListItemAction.Open:
|
case BookmarkListItemAction.Open:
|
||||||
router.navigate({ to: `/bookmarks/${bookmark.id}` })
|
router.navigate({ to: `/bookmarks/${bookmark.id}` })
|
||||||
@@ -45,6 +43,12 @@ const useBookmarkPageStore = create<BookmarkPageState>()((set, get) => ({
|
|||||||
case BookmarkListItemAction.Delete:
|
case BookmarkListItemAction.Delete:
|
||||||
set({ bookmarkToBeDeleted: bookmark, activeDialog: ActiveDialog.DeleteBookmark })
|
set({ bookmarkToBeDeleted: bookmark, activeDialog: ActiveDialog.DeleteBookmark })
|
||||||
break
|
break
|
||||||
|
|
||||||
|
case BookmarkListItemAction.CopyLink:
|
||||||
|
await navigator.clipboard.writeText(bookmark.url)
|
||||||
|
get().showStatus("Link copied to clipboard!")
|
||||||
|
break
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -57,6 +61,13 @@ const useBookmarkPageStore = create<BookmarkPageState>()((set, get) => ({
|
|||||||
setLayoutMode(mode: LayoutMode) {
|
setLayoutMode(mode: LayoutMode) {
|
||||||
set({ layoutMode: mode })
|
set({ layoutMode: mode })
|
||||||
},
|
},
|
||||||
|
|
||||||
|
showStatus(message: string) {
|
||||||
|
set({ statusMessage: message })
|
||||||
|
setTimeout(() => {
|
||||||
|
set({ statusMessage: "" })
|
||||||
|
}, STATUS_MESSAGE_DURATION_MS)
|
||||||
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
export { LayoutMode, ActiveDialog, useBookmarkPageStore }
|
export { LayoutMode, ActiveDialog, useBookmarkPageStore }
|
||||||
|
Reference in New Issue
Block a user